Java泛型是不变的,因此不可能进行这样的转换:
List<Object> li = (List<Object>)new ArrayList<Integer>();
但是在第4行的以下代码中,我可以从List<Integer>
转换为List<T>
,其中T
可以是任何类型。为什么允许这种类型的演员?
我知道它会生成关于未经检查的强制转换的警告,但重点是在参数化方法中可以进行此强制转换,但在普通代码中则不行。请记住,泛型是不变的,为什么允许它?在使用List<Integer>
的正常代码中,我只能将其强制转换为List<Integer>
,这是没有意义的,其他强制转换是非法的。那么在第4行允许这样的演员有什么意义呢?
我知道泛型类型在编译时被删除,并以List xlist = (List)list
结束,但在删除这些类型之前,显然不应该允许此强制转换,除非仅在有人通过Integer时才接受作为el
没有多大意义。
class Test {
public static <T> void t(List<Integer> list, T el) {
List<T> xlist = (List<T>)list; //OK
xlist.add(el);
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
t(list, "a");
t(list, "b");
//prints [a, b] even if List type is Integer
System.out.println(list);
}
}
答案 0 :(得分:5)
在Java中,进行显式转换是一个编译错误,在编译时已知该转换始终不正确或始终正确。从List<Integer>
到List<Object>
的强制转换在编译时始终是不正确的,因此不允许。从List<Integer>
到List<T>
的强制转换在编译时并不知道总是不正确 - 如果T
为Integer
并且T
为$i = 0;
foreach($records as $r) {
$html .= '<tr>
<td>'.escape($r->tecnologia).'</td>
<td>'.escape($r->normaespecificacion).'</td>
<td><img src="functions/'.escape($r->foto).'"></td>
<td>'.escape($r->marca).'</td>
<td>'.escape($r->modelo).'</td>
<td>'.escape($r->descripcion).'</td>
<td>$'.escape($r->preciounitario).'</td>
<td>$'.escape($r->iva).'</td>
<td>$'.escape($r->instalacion).'</td>
<td>$'.escape($r->totalcosto).'</td>
<td>'.escape($r->garantia).'</td>
<td><input type="text" value="0" class="imp" size="2" /></td>
</tr>';
$i = $i+1;
}
,那么这是正确的在编译时不知道。
答案 1 :(得分:1)
我想答案是这个演员表是可能的,因为Integer
可以作为参数el
传递,在这种情况下,演员表是正确的。在除Integer之外的所有其他类型的情况下,它将是非法的。但是正如我在泛型中看到的那样,如果至少有一种类型可以提供正确的强制转换(Integer
),那么编译器不会给出错误,但警告,即使所有其他情况都无效。 / p>
答案 2 :(得分:0)
Object是Integer类的超类。 List<Object>
不是类List<Integer>
的超类,但是,如果您希望List<Object>
引用List<Integer>
,则可以使用百搭号(?)。 / p>
List<?> list1 = new List<Object>();
List<?> list2 = new List<Integer>();
list1 = list2;