Метод copy () в Java - есть такая вещь? - PullRequest
2 голосов
/ 26 мая 2011

Я следую хорошо известному учебнику IBM по синтаксическому анализу RSS-канала. Я проверил это, и я получаю список только первого пункта. В 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 внутри внутреннего класса защищать другим методом.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 26 мая 2011

Экземпляр currentMessage используется в качестве накопителя для проанализированных атрибутов сообщения, и, когда сообщение закончено, копия текущего сообщения сохраняется в списке.Само текущее сообщение при копировании не изменяется, а его атрибуты перезаписываются атрибутами следующего сообщения.Без copy список messages в конечном итоге будет содержать один и тот же экземпляр сообщения снова и снова.

Так что метод copy должен вести себя как clone, и этот метод действительно отсутствует всписок.

2 голосов
/ 26 мая 2011

мы можем видеть, что currentMessage финал, что означает, что он неизменен

Это не правда! Если сделать переменную final, значит, ее нельзя переназначить, поэтому переменная неизменна, если вы хотите так ее назвать. Но объект, на который он указывает, не является неизменным, если он не предназначен для того, чтобы быть неизменным!

И вы можете видеть это даже из своего кода:

final Message currentMessage = new Message();

Вы сами присваиваете ему значения в коде позже, и компилятор не жалуется:

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

Мой вопрос: зачем вам сообщение, чтобы оно было неизменным? Неизменность является проблемой, только если у вас есть параллельные потоки, обращающиеся к данным (и манипулирующие ими) Это не должно происходить в парсере каналов, нет причин изменять входящее сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...