Java中的copy()方法 - 任何这样的事情?

时间:2011-05-26 19:11:03

标签: java rss copy immutability final

我正在关注着名的IBM tutorial解析RSS提要。我测试了它,我只获得了第一个项目的列表。在AndroidSaxFeedParser中,我们可以看到currentMessage是final,这意味着它无法更改,当我编写自己的实现时,我从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   用不同的方法解决。

谢谢!

2 个答案:

答案 0 :(得分:2)

  

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

那不是真的!使变量final意味着它不能被重新赋值,因此如果要调用它,变量是不可变的。但它所指出的对象并非一成不变,除非它被设计为不可变的!

即使你的代码也可以看到:

final Message currentMessage = new Message();

您稍后会在代码中为其分配值,并且编译器没有抱怨:

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

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

答案 1 :(得分:2)

currentMessage实例用作已解析消息属性的累加器,当消息完成解析时,当前消息的副本将存储在列表中。当前消息本身通过复制保持不变,其属性将被以下消息的属性覆盖。如果没有copymessages列表将一遍又一遍地包含完全相同的消息实例。

因此copy方法的行为应该与clone类似,实际上该列表中缺少该方法。