Когда я должен использовать метод java 5 класса? - PullRequest
12 голосов
/ 28 октября 2008

Просматривая код, я наткнулся на следующий код

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto));

и я хотел бы знать, есть ли у этого способа преимущество перед

trTuDocPackTypdBd.update((TrTuDocPackTypeDto)packDto);

Я спросил ответственного разработчика, и он сказал, что использовал его, потому что он был новым (что не кажется мне особенно веской причиной), но я заинтригован, когда захочу использовать метод. 1007 *

Ответы [ 5 ]

20 голосов
/ 28 октября 2008

Эти утверждения не идентичны. Метод приведения является обычным вызовом метода (invokevirtual инструкция JVM), тогда как другой является языковой конструкцией (checkcast инструкция). В случае, который вы показываете выше, вы должны использовать вторую форму: (TrTuDocPackTypeDto) packDto

Метод cast используется в рефлексивном программировании с обобщениями, когда у вас есть экземпляр класса для некоторого типа переменной. Вы можете использовать это так:

public <T> Set<T> find(Class<T> clz, Filter criteria) {
  List<?> raw = session.find(clz, criteria); /* A legacy, un-generic API. */
  Set<T> safe = new HashSet<T>();
  for (Object o : raw) 
    safe.add(clz.cast(o));
  return safe;
}

Это дает вам безопасный способ избежать неправильной альтернативы простого приведения необработанного типа к универсальному типу:

/* DO NOT DO THIS! */
List raw = new ArrayList();
...
return (List<Widget>) raw;

Компилятор предупредит вас, Unchecked cast from List to List<Widget>, что означает, что в многоточии кто-то мог добавить Gadget в необработанный список, что в конечном итоге приведет к ClassCastException, когда вызывающая программа итерит по возвращенному списку предполагается) Widget экземпляров.

4 голосов
/ 28 октября 2008

Основной случай для этого (IME) - когда вам нужно безопасно привести общий класс / метод. Из-за стирания типа вы не можете привести к T, но если вам был предоставлен параметр Class<? extends T>, вы можете использовать его для преобразования, и результат будет назначен переменной типа T.

0 голосов
/ 13 марта 2009

с первой формой

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto));

Вы можете сделать это:

public void dynamicCast( Class clazz, Object o ) { 
     this.x = clazz.cast( o );
}

Со вторым ты не можешь. Класс кастинга должен быть жестко закодирован.

Зачем вам использовать переменную для приведения в первую очередь? Это другой вопрос. :) Первое, что приходит на ум, это то, что вы не знаете (во время компиляции) класс, к которому будет приведен класс.

0 голосов
/ 13 марта 2009

Я не могу найти пример, где возможен метод приведения, а синтаксис приведения - нет. Однако, глядя на код, кажется, что в случае, если приведение невозможно, метод броска генерирует исключение ClassCastException без информации о типе, в то время как синтаксис преобразования даст вам некоторые подсказки (как, например, «не удалось привести Snoopy к TyrannosorusRex»). «) :

/**
 * Casts an object to the class or interface represented
 * by this <tt>Class</tt> object.
 *
 * @param obj the object to be cast
 * @return the object after casting, or null if obj is null
 *
 * @throws ClassCastException if the object is not
 * null and is not assignable to the type T.
 *
 * @since 1.5
 */
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
    throw new ClassCastException();
return (T) obj;
}
0 голосов
/ 28 октября 2008

Оба эти утверждения идентичны. Выберите тот, который вы найдете более читабельным. Второй метод более распространен в моем опыте, и это тот, который я предпочитаю.

Я склонен использовать метод приведения только тогда, когда я работаю с отражением, и в этой ситуации он выглядит лучше. В остальное время я использую второй способ кастинга.

...