2013-06-12 51 views
0

里面我不知道为什么下面的一般定义不会产生编译器警告:原始类型的一般定义

class MyClass<T extends List> { } 

和上面的定义是如何

class MyClass<T extends List<?>> { } 

不同每当你了解泛型,您会了解应该如何避免原始类型,因此,无论何时处理泛型类型,都会收到编译器警告。然而,第一个定义中的原始类型不会产生这样的警告。

其次,我不知道原始类型和泛型之间的确切的子类型定义是如何的。根据this summary,原始类型是类型检查的“退出”类型,因此只要涉及原始类型,类型检查就无效。这个假设是否正确?这是如何影响上述“原始”通用定义的?

谢谢你的帮助!

UPDATE:我明白你在说什么。但是,这并不是我所困惑的。看着这样的场景:

class MyClass<T extends MyClass<T>> {} 

public void callWildcard1(MyClass<?> node) { 
    callBound1(node); 
} 

public <T extends MyClass<T>> void callBound1(T node) { 
    // Do something 
} 

public void callWildcard2(MyClass<?> node) { 
    callBound2(node); 
} 

public <T extends MyClass> void callBound2(T node) { 
    // Do something 
} 

callWildcard1callBound1第一个电话是不允许的,因为一般的约束。然而第二个是允许的。如何在没有“内部原始类型”的情况下执行第一次调用?我不明白为什么编译器会禁止第一个。没有任何参数有效的通配符参数暗示? extends MyClass<?>

更新2:我发现通过试错,我可以通过定义解决的问题:

public <T extends MyClass<? extends T> void callBound2(T node) { 
    // Do something 
} 

即使我不明白为什么。但是,还有更多的困惑,在这个例子看时:(这是什么其实我试图做一个非常简单的版本)

public void call() { 
    genericCall1(new MyFilter<MyClass<?>>(), MyClass.class); 
    genericCall2(new MyFilter<MyClass<?>>(), MyClass.class); 
} 

public <T extends MyClass<? extends T>> void genericCall1(MyFilter<T> filter, Class<? extends T> filterBoundary) { 
    // Do something. 
} 

public <T extends MyClass<? extends T>, U extends T> void genericCall2(MyFilter<T> filter, Class<? extends U> filterBoundary) { 
    // Do something. 
} 

class MyClass<T extends MyClass<T>> { } 

class MyFilter<T extends MyClass<? extends T>> { } 

为什么genericCall1禁止genericCall2是不是?再次,我通过学术猜测找到了解决方案,而不是真正的理解。有时,在使用Java及其泛型时,我想哭...

+0

我一个让华林“List是原始类型引用泛型类型列表应该是参数化。”与JDK 1.6 – sanbhat

+0

在第一'MyClass'定义您提供这样一种类型,是'List',这就是为什么你没有得到警告。 – Sam

回答

2

不同之处在于,当您在MyClass中使用class MyClass<T extends List> { }时,您将失去类型安全性。

例如:

class A <T extends List<?>>{ 
    void someFunc(T t) { 
     t.add(new Object());//compilation error 
    } 

} 

class B <T extends List>{ 
    void someFunc(T t) { 
     //compiles fine 
     t.add(new Object()); 
     t.add("string"); 
     t.add(new Integer(3)); 
    } 
} 
+0

我想这基本上是我的问题的答案。我用另一个问题来提炼我的实际意图。 http://stackoverflow.com/questions/17061292/java-generics-raw-types-inside-of-generic-definition –