java - 泛型定义内的原始类型

标签 java generics types raw-types subtyping

我想知道为什么以下通用定义不会产生编译器警告:

class MyClass<T extends List> { }

上面的定义有何不同

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

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

其次,我想知道原始类型和泛型类型之间的确切子类型定义如何。根据this summary ,原始类型是类型检查的“选择退出”,因此只要涉及原始类型,类型检查就处于不活动状态。这个假设正确吗?这对上述“原始”通用定义有何影响?

感谢您的帮助!

更新:我明白你在说什么。然而,这并不是我困惑的地方。看看这个场景:

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 及其泛型时,我想哭......

最佳答案

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

例如:

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));
    }
}

关于java - 泛型定义内的原始类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17061292/

相关文章:

java - 谷歌应用引擎错误 : Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager

java - 获取 SQL 查询响应中每个重复记录的计数

c# - 为什么不能在xunit.net理论中将List<int>转换为TCollection?

function - 测试 Dart 值是否实际上是一个函数?

scala - "val a:A = new B ",有什么意义?

java - 如何通过仅保留所有树共有的节点来合并多棵树

java - Joda-Time,如何获取字符串解析的格式?

Java:子类化泛型类

c#-4.0 - C#中动态和T的实际区别是什么

c++ - 为什么 C++ 的 void 类型只是三心二意的单元类型?