[英]java generic method warning “Unchecked cast”
我相信这就是警告的原因:Java允许向下转换,即将类型X的对象转换为X的子类。但是,这需要在运行时进行检查。 例如:
Object x1 = <... something that returns an object that may be a String ...>;
String x2 = (String)x1;
演员将尝试将x1
视为String
。 但是x1
可以是任何Object
。 它可能是也可能不是String
。 只有当x1
实际上是一个String
; 否则你在运行时得到一个ClassCastException
。
代码中的问题是T
是View
的子类,这意味着强制转换通常会导致在运行时执行相同类型的检查。 但是,由于类型擦除,程序在代码中此时实际上并没有关于T
类的信息,这意味着它无法执行检查。 因此,您将使用未经检查的操作收到有关该程序的警告。 程序无法保证,当此方法返回时,返回的对象实际上将是T
类的实例。
我尝试了一些测试用例,发现检查通常发生在调用泛型方法的语句中。 假设View2
扩展了View
,并且您希望以返回View2
的方式使用find
。 然后:
View2 v = YourClass.<View2>find(x, id);
如果findViewById
找到的对象实际上不是View2
,那么你将得到一个ClassCastException
。 但:
View v = YourClass.<View2>find(x, id);
假设findViewById
返回其他一些视图。 基于我的测试,即使type参数是View2
,也不会抛出异常; 因为这被分配到一个View
,如果结果是其他视图,它将正常工作,不会检查View2
。
String s = YourClass.<View2>find(x, id).toString();
假设findViewById
返回其他一些视图。 当我尝试这个时,我认为它不会抛出异常,因为另一个视图也会有toString()
(就像所有的Object
一样)。 但这确实抛出了ClassCastException
。
我不知道是否有一个很好的方法来解决它。 一种可能性是添加第三个参数来find
以表示T
的类,并使用其cast
方法:
public static <T extends View> T find(View view, int id, Class<T> theClass) {
return theClass.cast(view.findViewById(id));
}
View v = YourClass.find(x, id, View2.class);
这有效 - 如果findViewById
返回错误的类,它会从cast()
方法抛出异常。 但是,为每次使用添加第三个参数可能不太吸引人,即使它可能允许您从调用中消除显式泛型类型参数。
我认为这是一个可以忽略警告的情况,并使用@SuppressWarnings("unchecked")
来停止警告显示,如果你可能有时程序可能会继续而不是抛出异常当findViewById
返回错误的视图时。
( 免责声明:我的测试是使用Java 8进行的。我没有使用任何在Java 7中无效的东西。但是如果Android仍然没有完全实现Java 7,我写的一些内容可能是错误的。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.