java - 奇怪的泛型行为。早早被抹杀?

标签 java generics javac type-erasure

今天我遇到了 Java 泛型的一些奇怪行为。以下代码可以正常编译并按您预期的方式工作:

import java.util.*;

public class TestGeneric
{
    public static void main(String[] args)
    {
        GenericClass<Integer> generic = new GenericClass<Integer>(7);
        String stringFromList = generic.getStringList().get(0);
    }

    static class GenericClass<A>
    {
        private A objA;
        private List<String> stringList;

        GenericClass(A objA)
        {
            this.objA = objA;
            stringList = new ArrayList<String>();
            stringList.add("A string");
            stringList.add("Another string");
        }

        A getObjA()
        {
            return objA;
        }

        List<String> getStringList()
        {
            return stringList;
        }
    }
}

但是如果您将泛型变量的类型更改为 GenericClass(注意没有类型参数),编译将失败并显示消息“不兼容的类型:java.lang.Object 无法转换为 java.lang.String”。

这个问题似乎发生在任何包含具有具体类型参数的通用对象的通用类中。一些谷歌搜索没有发现任何东西,JLS 没有提到这种情况?我做错了什么或者这是 javac 中的错误?

最佳答案

原始类型GenericClass被认为已被删除,包括类未声明的泛型类型。所以getStringList返回原始 List而不是参数化 List<String> .

我发现很难在 Java 规范中找到一件事来指出这一点,但这是正常行为。

这是另一个例子。

public class Test {
    public static void main(String[] args) {
        String s;

        // this compiles
        s = new Generic<Object>().get();
        // so does this
        s = new Generic<Object>().<String>get();

        // this doesn't compile
        s = new Generic().get();
        // neither does this
        s = new Generic().<String>get();
    }
}

class Generic<A> {
    <B> B get() { return null; }
}

两者都是 AB被删除,但B由方法声明。很好奇。

这种令人惊讶的细微差别就是为什么必须警告不要使用原始类型。

关于java - 奇怪的泛型行为。早早被抹杀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24254210/

相关文章:

Java函数使用计算机时钟每分钟执行任务

java - 使用 for 循环从 map 列表中检索 map

Java Azure Function - 在 BLOB 容器中上传文件

ios - 检查 AnyObject 是否是 Swift 中的泛型类型

java - 相当于Java中的C++头文件?

java - 运行单文件源代码 Java 程序时如何传递编译器选项?

java - 使用 Jsoup,我如何获取每个链接中的每个信息?

c# - 在方法签名中使用泛型有什么好处?

java - 使用有界通配符推断类型的问题

java - 是否可以在注释处理环境中获取包中的所有 TypeElement?