Java: как использовать clone () и как насчет проверки приведения - PullRequest
4 голосов
/ 15 октября 2010

Этот код:

class RawStringIterator {
        java.util.Stack<State> stateStack = new java.util.Stack<State>();
        RawStringIterator(RawStringIterator i) {
              stateStack = (java.util.Stack<State>) i.stateStack.clone();
        }
        /* ... */
}

выдает мне это предупреждение:

Type safety: Unchecked cast from Object to Stack<Utils.OperatorTree.RawStringIterator.State>

Я думаю, я могу проигнорировать предупреждение здесь.Но мне интересно, как вообще использовать clone()?Всегда ли мне нужно использовать @SuppressWarnings("unchecked") каждый раз, когда я использую clone()?Или я должен всегда делать лишнюю дополнительную проверку?

Ответы [ 4 ]

12 голосов
/ 15 октября 2010

Если у вас есть выбор, лучше всего вообще не внедрять / использовать clone(), потому что это сломанный API . Просто реализуйте / используйте вместо этого конструктор копирования.

Если по какой-то неотложной причине вы должны использовать clone(), но можете изменить его реализацию, рассмотрите возможность объявления Stack<T>.clone() для возврата Stack<T> вместо Object - ковариантные типы возврата допустимы начиная с Java5.

Обновление: , если Stack, о котором идет речь, java.util.Stack, рассмотрим его Javadoc :

Более полный и согласованный набор операций стека LIFO обеспечивается интерфейсом Deque и его реализациями, которые следует использовать в предпочтении этому классу.

И, например, ArrayDeque предоставляет конструктор копирования .

2 голосов
/ 15 октября 2010

Здесь нет способа избежать каста. clone() возвращает Object, если это java.util.Stack, он не использует ко-вариантные типы возврата.

Если это не java.util.Stack, тогда не реализовывайте clone() - действительно сложно сделать это правильно. Вместо этого создайте конструктор копирования.

0 голосов
/ 15 октября 2010

Да, вам нужно явно подавлять предупреждения при каждом использовании clone().

. Это одна из причин, по которой вы можете предпочесть использовать конструкторы копирования вместо clone(), если они доступны.

Кстати, в вашем коде, когда используется конструктор RawStringIterator(RawStringIterator i), первая инициализация stateStack не нужна:

class RawStringIterator {
    Stack<State> stateStack = new Stack<State>();
    RawStringIterator(RawStringIterator i) {
          stateStack = (Stack<State>) i.stateStack.clone();
    }
    /* ... */
}

Возможно, вы захотите удалить это.*

0 голосов
/ 15 октября 2010

У вас очень мало выбора, кроме как игнорировать его.

Хотя это и не имеет прямого отношения (потому что вы не пишете clone() метод), эта запись в FAQ по обобщенным Java * хорошо читает (как и весь FAQ!)

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