Java 中的 copy() 方法 - 有这样的事情吗?

发布于 2024-11-09 22:55:08 字数 2422 浏览 2 评论 0原文

我正在遵循有关解析 RSS 提要的著名 IBM 教程。我测试了它,我只得到第一个项目的列表。在 AndroidSaxFeedParser 中,我们可以看到 currentMessage 是最终的,这意味着它无法更改,当我编写自己的实现时,我删除了 copy() 调用currentMessage 因为编译器找不到这个方法(因此在我看来是复制的数据集)。

public class AndroidSaxFeedParser extends BaseFeedParser {

    public AndroidSaxFeedParser(String feedUrl) {
        super(feedUrl);
    }

    public List<Message> parse() {
        final Message currentMessage = new Message();
        RootElement root = new RootElement("rss");
        final List<Message> messages = new ArrayList<Message>();
        Element channel = root.getChild("channel");
        Element item = channel.getChild(ITEM);
        item.setEndElementListener(new EndElementListener(){
            public void end() {
                // Here, what's copy()?!!
                messages.add(currentMessage.copy()); 
            }
        });
        item.getChild(TITLE).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setTitle(body);
            }
        });
        item.getChild(LINK).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setLink(body);
            }
        });
        item.getChild(DESCRIPTION).setEndTextElementListener(new 
EndTextElementListener(){
            public void end(String body) {
                currentMessage.setDescription(body);
            }
        });
        item.getChild(PUB_DATE).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setDate(body);
            }
        });
        try {
            Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, 
root.getContentHandler());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return messages;
    }
}

所以我的问题是,copy() 是什么,我是否在这里遗漏了一些重要的东西?

编辑 基本上,我想知道的是:

  • 什么是copy()?为什么它似乎对每个人都有效,但对我不起作用? (所有提到本教程的人都没有对此说过任何话。)

另外,我之所以将其定为最终版本是因为编译器要求我这样做。如果删除 final 关键字,我会收到以下错误消息:

不能引用非最终变量 内部类中的 currentMessage 以不同的方法进行防御。

谢谢!

I am following the well famous IBM tutorial on parsing an RSS feed. I tested it and I am getting a list of the first item only. In the AndroidSaxFeedParser, we can see that currentMessage is final which means that it can't be changed, and when I wrote my own implementation I removed the copy() call from currentMessage because the compiler doesn't find this method (hence the replicated set of data in my opinion).

public class AndroidSaxFeedParser extends BaseFeedParser {

    public AndroidSaxFeedParser(String feedUrl) {
        super(feedUrl);
    }

    public List<Message> parse() {
        final Message currentMessage = new Message();
        RootElement root = new RootElement("rss");
        final List<Message> messages = new ArrayList<Message>();
        Element channel = root.getChild("channel");
        Element item = channel.getChild(ITEM);
        item.setEndElementListener(new EndElementListener(){
            public void end() {
                // Here, what's copy()?!!
                messages.add(currentMessage.copy()); 
            }
        });
        item.getChild(TITLE).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setTitle(body);
            }
        });
        item.getChild(LINK).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setLink(body);
            }
        });
        item.getChild(DESCRIPTION).setEndTextElementListener(new 
EndTextElementListener(){
            public void end(String body) {
                currentMessage.setDescription(body);
            }
        });
        item.getChild(PUB_DATE).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setDate(body);
            }
        });
        try {
            Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, 
root.getContentHandler());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return messages;
    }
}

So my question is, what's copy(), am I missing something important here?

Edit
Basically, what I want to know is:

  • What is copy()? and why does it seem to work with everyone but not me? (all the people mentioning the tutorial never said anything about it..)

Also, the reason why I am making it final is because the compiler is asking me to do it. If I remove the final keyword, I get the following error message:

Cannot refer to a non-final variable
currentMessage inside an inner class
defiend in a different method.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

左秋 2024-11-16 22:55:08

currentMessage 实例用作已解析消息属性的累加器,当消息解析完成时,当前消息的副本将存储在列表中。当前消息本身不会因复制而改变,并且其属性会被后续消息的属性覆盖。如果没有copymessages列表最终将一遍又一遍地包含完全相同的消息实例。

因此,copy 方法的行为应该类似于 clone,而且列表中确实缺少该方法。

The currentMessage instance is used as an accumulator for parsed message attributes, and when a message is finished parsing, a copy of the current message is stored in the list. The current message itself is unchanged by copying, and its attributes are overwritten with the attributes of the following message. Without the copy, the messages list would end up containing the very same message instance over and over.

So the copy method should behave like clone, and indeed that method is missing from the listing.

请止步禁区 2024-11-16 22:55:08

我们可以看到 currentMessage 是
Final 这意味着它是不可变的

这不是真的!将变量设置为最终变量意味着它不能被重新分配,因此如果您想这样称呼它,则该变量是不可变的。但它指向的对象并不是不可变的,除非它被设计成不可变的!

即使从您的代码中您也可以看到这一点:

final Message currentMessage = new Message();

您稍后在代码中自己为其赋值,并且编译器不会抱怨:

public void end(String body) {
    currentMessage.setTitle(body);
}

我的问题是为什么您首先需要一条不可变的消息。仅当您有并发线程访问(和操作)数据时,不变性才是一个问题。这不应该发生在提要解析器中,没有理由更改传入消息。

we can see that currentMessage is
final which means that it's immutable

That's not true! Making the variable final means it can't be reassigned, so the variable is immutable if you want to call it that. But the object it points to is not immutable unless it is designed to be immutable!

And you can see that even from your code:

final Message currentMessage = new Message();

You are assigning values to it later in the code yourself, and the compiler isn't complaining:

public void end(String body) {
    currentMessage.setTitle(body);
}

My question is why you need a message to be immutable in the first place. Immutability is an issue only if you have concurrent threads accessing (and manipulating) the data. This should not happen in a feed parser, there's no reason to change an incoming message.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文