2013-10-24 93 views
0

首先创建一些代码(Java 7),以说明我的问题。适用于任何列表和泛型/类型擦除方面的方法

import java.util.*; 

class Generics101 { 



    public static void addTrue(List list) { 
     list.add(true); 
    } 

    public static void main(String[] args) { 
     List<Integer> testList = new ArrayList<>(); 

     addTrue(testList); 
     System.out.println(testList.get(0)); 

     // testList.add(true); // will not compile when uncommented 

    } 
} 

我有以下两个问题:

  1. addTrue方法Eclipse中暗示,它不喜欢raw types。当我尝试更改方法参数以使用通配符List<?> list时,它不会编译。我查看了Generics Tutorial,但找不到答案。我在这里错过了什么,我应该在哪里读到它?

  2. 同样tutorial指出:“泛型被引入Java语言在编译时提供更严格的类型检查...”据我所知,由于type erasure这样的执法不能在运行时等发生我上面的代码编译并运行。如果注释行没有注释,它会触发编译错误,所以我假设tighter type checks在同一个方法中有效。这种执法的确切范围是什么?它是如何正式定义的?

+0

'addTrue' _should_只适用于'List '。 –

回答

3

当我试图改变方法参数使用通配符名单列表不会编译。

它不会编译,因为您不能在List<?>中添加任何内容。因为您不知道哪种类型的List实际上即将到来。例如,只采取您目前的情况。您正在通过List<Integer>。它将成功传递到List<?>。没有问题。但您正在添加trueboolean类型。如果编译器允许的话,它会在运行时抛出ClassCastException。所以,这是不允许的。

所以我假设更紧密的类型检查是在同一个方法中生效的。这种执法的确切范围是什么?

不,不是这样的。这不是类型检查是在一定范围内完成的。无论何处使用泛型,它都会被强制执行。如果使用适当的泛型,则不会编译当前的代码,因为您正试图将boolean类型添加到List<Integer>。你为什么期望这个工作?

试着改变你的方法泛型方法,你会看到,这将无法编译:

public static <T> void addTrue(List<T> list) { 
    list.add(true); // Won't compile 
} 

我通过泛型教程看了,但找不到答案。我在这里错过了什么,我应该在哪里读到它?

那么,这是Oracle的标准教程。这就是你应该阅读的地方。除此之外,你还可以在Java Generics FAQs - Angelika Langer.

+0

谢谢你的回复。 “*如果与适当的仿制药一起使用*”是什么意思? –

+0

@ PM77-1正确使用泛型的手段。就像如果你让你的方法是通用的那样,那么当你通过除了'List '之外的任何东西时,代码将无法编译。 –

+0

回复:' void'。我假设''代表方法的结果类型,因此与'void'不兼容。 –