繁体   English   中英

java泛型方法警告“未经检查的强制转换”

[英]java generic method warning “Unchecked cast”

我写了一个替换View.findViewById(int id) ,但是我得到了一个警告: 在此输入图像描述

这个方法有什么问题吗? 或者如何避免它?

我相信这就是警告的原因: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

代码中的问题是TView的子类,这意味着强制转换通常会导致在运行时执行相同类型的检查。 但是,由于类型擦除,程序在代码中此时实际上并没有关于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM