Mik*_*iku 6 java generics instanceof
我正在寻找一种使用通用函数优化代码库中某些内容的方法。有一个带有返回类型的函数,该函数List<Object>可能具有return type List<SpecifiedType>。
贝娄是该函数的简约版本function。它采用参数类型,并基于它调用相应的函数(在此限于String)或泛型函数。
public static ArrayList<String> forString(){
ArrayList<String> res = new ArrayList<>();
// Fetching and processing data specific to String
return res;
}
public static <T> ArrayList<T> forGeneric(Class<T> type){
ArrayList<T> res = new ArrayList<>();
// Fetching data
return res;
}
public static <T> ArrayList<T> function(Class<T> type){
if(type == String.class)
return (ArrayList<T>) forString();
return forGeneric(type);
}
Run Code Online (Sandbox Code Playgroud)
上面的函数的目标是这样调用的: ArrayList<SomeType> someTypes = function(SomeType.class);
关于以上代码,我注意到了两件事:
投射到ArrayList<T>尽管我们知道,如果类型需要String被作为参数传递它将返回ArrayList<String>就像forString()方法
演员要ArrayList<T>给予Unchecked cast警告,即使返回类型将是ArrayList<String>
我的问题是是否有更好的方法(最好没有演员),如果没有,那为什么
首先,这个说法在逻辑上是错误的
if(type.isInstance(String.class))
Run Code Online (Sandbox Code Playgroud)
If typeis Class<String>thenisInstance正在检查参数是否是字符串实例。您传递的参数是一个类实例(具体来说, a Class<String>)。
如果你更喜欢,
String.class.isInstance(String.class) == false
Run Code Online (Sandbox Code Playgroud)
你的意思是
if(type == String.class)
Run Code Online (Sandbox Code Playgroud)
然而,即使解决了这个逻辑错误,您的代码仍然会出现未经检查的强制转换警告。
你缺少的部分就在这里
ArrayList<T>即使我们知道如果 String 类型作为参数传递,它也会ArrayList<String>像forString()方法一样返回
确切地。我们知道。但我们所知道的和编译器所知道的是两件不同的事情。编译器不够聪明,无法检查条件并意识到类型是正确的。可以想象它可能足够聪明,但事实并非如此。
这正是为什么这表现为警告而不是错误的原因。这是一个警告,因为您所做的事情可能是错误的;它并不是绝对错误的,否则根本无法编译。在这种情况下,警告应该提示您仔细检查您正在做的事情是否正确,然后您就可以愉快地抑制它。
@SuppressWarnings("unchecked")
public static <T> ArrayList<T> function(Class<T> type){
if(type == String.class)
return (ArrayList<T>) forString();
return forGeneric(type);
}
Run Code Online (Sandbox Code Playgroud)
最后——这可能是你设计的例子的产物——但所有这些方法都是无用的。与直接调用相比,似乎没有任何优势new ArrayList<>()。在运行时,实际实例是相同的,无论它来自 3 个方法中的哪一个。