通用定义内的原始类型 [英] Raw types inside of generic definition
问题描述
class MyClass< T extends List> 我不知道为什么以下泛型定义不会产生编译器警告。 {}
以上定义与 $ b $不同b
class MyClass< T extends List<>> {}
当您阅读泛型时,您会了解应该如何避免原始类型,你处理泛型类型,你会得到一个编译器警告。然而,第一个定义中的原始类型不会产生这样的警告。其次,我想知道原始类型和泛型之间的确切的子类型定义是如何的。根据本摘要,生类型是类型检查的退出类型,因此只要涉及原始类型,类型检查就无效。这个假设是否正确?那么这是如何影响上述原始泛型定义的?
感谢您的帮助! strong>更新:我明白你在说什么。但是,这并不是我所困惑的。看看这个场景:
class MyClass< T extends MyClass< T>> {}
public void callWildcard1(MyClass<?> node){
callBound1(node);
}
public< T extends MyClass< T>> void callBound1(T节点){
//做某事
}
public void callWildcard2(MyClass<> node){
callBound2(node);
}
public< T extends MyClass> void callBound2(T node){
//做某事
}
由于通用约束,不允许第一次调用 callWildcard1
至 callBound1
。然而第二个是允许的。如何在没有内部原始类型的情况下执行第一次调用?我不明白为什么编译器会禁止第一个。没有任何参数有效的通配符参数意味着?扩展MyClass<?>
?
更新2 :我通过试验和错误发现,通过定义来解决问题:
public< T extends MyClass<延伸T> void callBound2(T节点){
//做某事
}
偶数尽管我不太明白为什么。但是在看这个例子的时候,更令人困惑的是:(这是我真正想要做的一个非常简单的版本。)
public void call(){
genericCall1(new MyFilter< MyClass<>>(),MyClass.class);
genericCall2(new MyFilter< MyClass<>>(),MyClass.class);
}
public< T扩展MyClass<?延伸T>> void genericCall1(MyFilter< T> filter,Class<?extends T> filterBoundary){
//做某事。
}
public< T扩展MyClass<?延伸T>,U延伸T> void genericCall2(MyFilter< T> filter,Class<?extends U> filterBoundary){
//做些什么。
}
class MyClass< T extends MyClass< T>> {}
class MyFilter< T扩展MyClass<延伸T>>为什么 genericCall1
禁止,<?
> code> genericCall2 不是?再次,我通过学术猜测找到了解决方案,而不是真正的理解。有时候,在使用Java及其泛型时,我想哭... ...
不同之处在于,当您使用 class MyClass< T extends List> {}
在 MyClass
内部,您会失去安全性。
class A< T extends List<>> {
void someFunc(T t){
t.add(new Object()); //编译错误
}
}
class B< T extends List> {
void someFunc(T t){
//编译罚款
t.add(new Object());
t.add(string);
t.add(new Integer(3));
}
}
I wonder why the following generic definition does not produce a compiler warning:
class MyClass<T extends List> { }
and how the above definition is different to
class MyClass<T extends List<?>> { }
Whenever you read about generics, you read about how raw types should be avoided and consequently, whenever you handle generic types, you get a compiler warning. The raw type inside of the first definition does however not create such a warning.
Secondly, I wonder how the exact subtyping definition between raw types and generic types are. According to this summary, raw types are kind of an "opt-out" of type checking such that type checking is simply inactive whenever a raw type is involved. Is this assumption correct? And how does this effect the above "raw" generic definitions?
Thank you for your help!
UPDATE: I understand what you are saying. However, this is not what I am confused about. Look at this scenario:
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
}
The first call from callWildcard1
to callBound1
is not allowed because of the generic constraint. The second is however allowed. How can I perform the first call without "inner raw types"? I don't see why the compiler would forbid the first. Shouln't any parameter valid wildcard parameter imply ? extends MyClass<?>
?
UPDATE 2: I found out by trial and error, that I can solve the problem by defining:
public <T extends MyClass<? extends T> void callBound2(T node) {
// Do something
}
even though I do not quite understand why. But there is even more confusion, when looking at this example: (this is a very simple version of what I am actually trying to do.)
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>> { }
Why is genericCall1
prohibited and genericCall2
is not? Again, I found the solution by an academic guess instead of true understanding. Sometimes, when working with Java and its generics I want to cry...
The difference is that when you use class MyClass<T extends List> { }
inside MyClass
you lose type safety.
for example:
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));
}
}
这篇关于通用定义内的原始类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!