通用定义内的原始类型 [英] Raw types inside of generic definition

查看:139
本文介绍了通用定义内的原始类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆