鉴于此代码:
List<Integer> ints = new ArrayList<Integer>();
// Type mismatch:
// cannot convert from Class<capture#1-of ? extends List> to Class<List<Integer>>
Class<List<Integer>> typeTry1 = ints.getClass();
// Type safety:
// Unchecked cast from Class<capture#2-of ? extends List> to Class<List<Integer>>
Class<List<Integer>> typeTry2 = (Class<List<Integer>>) ints.getClass();
// List is a raw type. References to generic type List<E> should be parameterized
Class<? extends List> typeTry3 = ints.getClass();
有没有办法在没有错误或警告的情况下获取Class
的{{1}}?我可以很容易地抑制警告,但如果Java要求我禁止对此有效代码发出警告,我非常disappoint。
另一方面,如果警告抑制是唯一的方法,最安全的抑制是什么?
答案 0 :(得分:5)
这是Java中真正的Catch-22。
如果您不向List
添加泛型类型,编译器会发出警告:
// WARN: List is not typed
Class<? extends List> typeTry3 = ints.getClass();
这是因为,在大多数情况下,最好输入您的列表。
但是,由于类型擦除,Java无法在运行时找出List
的泛型类型,并且编译器知道这一点。因此,Class
上没有返回类型对象的方法:
// ERROR: ints.getClass() doesn't return a Class<List<Integer>>, it returns a Class<List>
Class<? extends List<? extends Integer>> var = ints.getClass();
因此必须将其强制转换为类型列表。但是,正如您所知,由于没有运行时类型检查,Java会警告您对类型化变量的任何强制类型转换:
// WARN: Casting to typed List
Class<List<Integer>> typeTry2 = (Class<List<Integer>>) ints.getClass();
任何试图解决这个问题的尝试本质上是一种混淆编译器的方法,并且不可避免地会令人费解。
那么你最好的选择是选择B:
另一方面,如果警告抑制是唯一的方法,最安全的抑制是什么?
禁止此警告的最安全方法是使@SuppressWarnings("unchecked")
注释尽可能本地化。将它们放在每个未经检查的演员表上方。这样就可以清楚地知道是谁造成了警告。
答案 1 :(得分:3)