我正在关注着名的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 用不同的方法解决。
谢谢!
答案 0 :(得分:2)
我们可以看到currentMessage是 final意味着它是不可变的
那不是真的!使变量final意味着它不能被重新赋值,因此如果要调用它,变量是不可变的。但它所指出的对象并非一成不变,除非它被设计为不可变的!
即使你的代码也可以看到:
final Message currentMessage = new Message();
您稍后会在代码中为其分配值,并且编译器没有抱怨:
public void end(String body) {
currentMessage.setTitle(body);
}
我的问题是为什么首先需要一条消息是不可变的。只有当您有并发线程访问(和操作)数据时,不变性才是问题。这不应该在Feed解析器中发生,没有理由更改传入的消息。
答案 1 :(得分:2)
currentMessage
实例用作已解析消息属性的累加器,当消息完成解析时,当前消息的副本将存储在列表中。当前消息本身通过复制保持不变,其属性将被以下消息的属性覆盖。如果没有copy
,messages
列表将一遍又一遍地包含完全相同的消息实例。
因此copy
方法的行为应该与clone
类似,实际上该列表中缺少该方法。