开发者

copy() method in Java - any such thing?

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.setDescri开发者_如何学运维ption(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!


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜