2015-11-23 2 views
0

У меня есть класс MyClass<GenericArg> Как я могу получить его класс? Я пробовал:Java: Получить класс класса с общим аргументом

MyClass<GenericArg>.class 

и он не компилируется.

Я пробовал MyClass.class, и он компилируется, но с предупреждением, и мне не нравятся предупреждения. Есть ли возможность избежать этого предупреждения (без ограничения, конечно!)?

РЕДАКТИРОВАТЬ:

У меня есть функция конструкции (класс MyClass) где Т расширяет AbstractClass

в методе конструкта, я экземпляр T и вернуть его:

myClass.newInstance(); 
return myClass; 

Когда слово, У меня есть:

public class SubClass<myEnum extends Enum<myEnum> extends AbstractClass<myEnum> 
{ 
    public static SubClass<myEnum> getSubClass() 
    { 
      return construct(SubClass.class); 
    } 
} 
+1

Какое предупреждение вы получаете? – Keews

+0

Это не помогает, что мы не знаем, чего вы пытаетесь достичь - пытаетесь ли вы получить ссылку «Class» для «MyClass» с определенным аргументом типа или только с сырым типом? –

+0

Не знаю ваш прецедент, но я использую MyClass , чтобы добавить гарантию времени компиляции, что T - это правильный тип экземпляра класса. – cYrixmorten

ответ

1

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

Является ли это точным?

По всем причинам, которые уже обсуждались, в Java 8 нет способа сделать это без предупреждения о компиляторе, но это не означает, что ваш код не является безопасным по типу. Предупреждение означает, что он не может гарантировать, что ваш код безопасен по типу. Если вы можете доказать себе, что ваш код в безопасности, то целесообразно (и полезно) подавить предупреждение для безопасного кода типа.

Вот пример метода, который создает и возвращает объект того же типа, что в комплекте поставки аргумента:

public static <T> T createInstanceFrom(T myInstance) { 
    @SuppressWarnings("unchecked") 
    Class<T> myType = (Class<T>) myInstance.getClass(); 
    T instance = myType.newInstance(); 
    return instance; 
} 

Потому что нет типа безопасного способа бросить к универсальному типу, приведенное выше, генерирует предупреждение о компиляторе, сообщающее вам, что ваш код не может быть безопасным по типу. Однако вы можете сами проанализировать код. В этом случае myInstance, instance и myType должны всегда иметь общий объект Class. Поскольку вы можете доказать, что код безопасен по типу, важно подавить предупреждение (и добавить комментарий, объясняющий, почему код является безопасным).

Вы можете доказать, что это типобезопасно:

List<String> stringList = new ArrayList<>(); 

List<String> myList1 = createInstanceFrom(stringList); 
List<Integer> myList2 = createInstanceFrom(stringList); 
List myList3 = createInstanceFrom(stringList); 

Метод createInstanceFrom -must- возвращает объект с тем же типом в качестве аргумента, поэтому линия с myList1 компилирует, но линия с myList2 генерирует ошибка компилятора. Строка с myList3 компилирует, но генерирует предупреждение компилятора, потому что, опять же, если вы используете необработанный тип, компилятор не может гарантировать вам, что этот код безопасен по типу. Здесь, однако, нет способа доказать, что этот код безопасен (и поэтому этот код должен быть переработан в нечто более безопасное).

+0

Большое спасибо за полный ответ. Это, конечно, не то, что я ожидал, но теперь я понимаю, почему я не могу избежать предупреждения. – Hermios

-2

, похоже, есть общее предупреждение, не обратить внимание

Два пути, чтобы получить класс:

Class c = MyStart.class; 
Class c = instanceOfAClass.getClass() 

или посредством отражения

+5

Предполагая, что кто-то должен игнорировать предупреждение, даже не видя, как характер предупреждения кажется мне очень плохой идеей. –

5

Класс буквального MyClass<GenericType>.class является незаконным, поскольку он не существует во время выполнения. Java дженерик реализуются стиранием и поэтому байтовые код:

MyClass<GenericType1> 
MyClass<GenericType2> 
MyClass 

один и тот же во время выполнения объекта класса. Хорошо, что вы получаете ошибку компилятора, потому что общий литерал класса не является безопасным для типов.

Компилятор Java гарантирует, что ваш код будет безопасным по типу, если он компилируется без ошибок или предупреждений. Когда вы получите это конкретное предупреждение, это связано с тем, что среда Java сообщает вам, что она не может гарантировать безопасность вашего кода. На этом этапе вы должны оценить свой код и определить, безопасно ли (или нет) то, что вы пытаетесь сделать.

Если это безопасный тип (и только если), то вы должны применить аннотацию @SuppressWarnings в кратчайшем возможном блоке кода с комментарием, объясняющим, как код по-прежнему безопасен. Если вы не можете придумать какой-либо такой комментарий, вы можете захотеть реорганизовать свой дизайн, чтобы добиться лучшей безопасности типов.

Смежные вопросы