Во-первых, это утверждение логически неверно
if(type.isInstance(String.class))
Если type
равно Class<String>
, то isInstance
проверяет, является ли аргумент экземпляром строки.Передаваемый вами аргумент является экземпляром класса (в частности, Class<String>
).
Если вы предпочитаете,
String.class.isInstance(String.class) == false
То, что вы имели в виду, было
if(type == String.class)
Однако даже после устранения этой логической ошибки в вашем коде по-прежнему будет отображаться предупреждение о неконтролируемом приведении.
Недостающая часть находится здесь
Требуется приведение к ArrayList<T>
хотя мы знаем , что если тип String передан в качестве параметра, он вернет ArrayList<String>
, как forString()
method
Точно. Мы знаем это.Но то, что мы знаем и то, что знает компилятор, это две разные вещи.Компилятор не достаточно умен, чтобы проверить условия и понять, что с типом все в порядке.Возможно, может быть достаточно умным, но это не так.
Именно поэтому это проявляется как предупреждение, а не как ошибка.Это предупреждение, потому что то, что вы делаете, потенциально неправильно;это не определенно неправильно, иначе он не будет компилироваться вообще.В этом случае предупреждение должно послужить подсказкой для вас, чтобы еще раз проверить, что вы делаете правильно, и тогда вы можете счастливо подавить это.
@SuppressWarnings("unchecked")
public static <T> ArrayList<T> function(Class<T> type){
if(type == String.class)
return (ArrayList<T>) forString();
return forGeneric(type);
}
Наконец - и это может быть артефактом вашего надуманного примера - но все эти методы бесполезны.Кажется, нет никакого преимущества перед прямым набором new ArrayList<>()
.Во время выполнения фактические экземпляры идентичны независимо от того, из какого из 3 методов они поступили.