java - 泛型方法中需要 Java 冗余强制转换
问题描述
我正在寻找一种方法来使用通用函数优化我们的代码库中的某些内容。有一个返回类型的函数List<Object>
可能有返回类型List<SpecifiedType>
。
Bellow 是该函数的极简版本,称为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);
}
目标是像这样调用上面的函数:ArrayList<SomeType> someTypes = function(SomeType.class);
关于上面的代码,我注意到了两件事:
Cast to
ArrayList<T>
是必需的,即使我们知道如果类型String
作为参数传递,它将ArrayList<String>
像forString()
方法一样返回Cast to
ArrayList<T>
给出Unchecked cast
警告,即使返回类型为ArrayList<String>
我的问题是有没有更好的方法(最好没有演员表),如果没有,那为什么
解决方案
首先,这个说法在逻辑上是错误的
if(type.isInstance(String.class))
If type
is Class<String>
thenisInstance
检查参数是否为字符串实例。您传递的参数是一个类实例(特别是 a Class<String>
)。
如果你更喜欢,
String.class.isInstance(String.class) == false
你的意思是
if(type == String.class)
但是,即使解决了这个逻辑错误,您的代码仍然会有未经检查的强制转换警告。
你缺少的部分就在这里
Cast to
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);
}
最后——它可能是你人为的例子的产物——但所有这些方法都是无用的。与直接调用相比,似乎没有任何优势new ArrayList<>()
。在运行时,无论它来自 3 个方法中的哪一个,实际实例都是相同的。
推荐阅读
- javascript - MomentJS inBetween 总是返回 false
- php - php laravel 多次为表创建模型实例
- php - 允许客户在 WooCommerce 中设置产品价格并通过某些验证添加到购物车
- wordpress - Elementor wordpress - 第一部分在移动设备中不可见
- azure - Azure Function App 中的 Task.Run()
- python - Python Pandas 交换列值
- c++ - 如何读取运行 QProcess 的输出并将特定数据保存到变量?
- docker - 将变量传递给 Dockerfile 并在 Tag 版本中使用它?
- javascript - 从外部文件访问 json 数据
- reactjs - React.js,显示两个彼此相邻的 Svg 图像,中间有空格