#java
#java
Вопрос:
Является ли это безопасным способом создания экземпляра (при условии, что T имеет доступный конструктор по умолчанию)?
<T>
public T defaultObj(T obj) throws Exception {
return (T) obj.getClass().newInstance();
}
Из-за стирания типа приведенные выше коды будут генерировать непроверенное предупреждение. Можно ли избавиться от этого предупреждения, кроме @SuppressWarnings?
Заранее большое спасибо!
Редактировать: Да, я знаю, мог бы я передать class<T> type
, что было бы намного лучше. Но давайте просто предположим, что пока об этом не может быть и речи.
Ответ №1:
Вы можете немного изменить подпись <T> T defaultObj(Class<T> obj)
, а затем newInstance()
вернет соответствующий объект.
Комментарии:
1. Спасибо за совет. Но давайте предположим, что сигнатура метода не может быть изменена. Безопасно ли использовать приведенные выше коды?
2. Да, я полностью согласен с axtavt.
3. Сигнатура метода должна быть записана. Не имеет никакого смысла делать подобные вещи (как и большинство реальных применений отражения).
Ответ №2:
Это именно то, что @SuppressWarnings
предполагается сделать: этот код безопасен (потому что вызов getClass()
объекта типа T
на самом деле дает Class<? extends T>
результат), но компилятор не может его понять (возвращаемое значение getClass()
объявляется как Class<?>
из-за ограничений дженериков) и генерирует предупреждение.
@SuppressWarnings
В этом случае его использование абсолютно законно, и вы не должны пытаться избегать его использования.
Комментарии:
1. Спасибо!! Это заверение, которое я надеялся услышать. 🙂
Ответ №3:
Можно ли избавиться от этого предупреждения, кроме @SuppressWarnings?
Вы могли бы ограничить T
расширение некоторого интерфейса, который предоставляет фабричный метод.
interface Newable<T>
{
T getNewInstance();
}
<T extends Newable<T>> T defaultObj(T obj)
{
return obj.getNewInstance();
}
пример реализации:
class Foo implements Newable<Foo>
{
@Override
public Foo getNewInstance() {
return new Foo();
}
}