泛型混淆:欺骗编译器

迈阿密滩

考虑一个代码:

public class GenericsConfusion {
    public static <T> Class<T> get(Class<T> clazz) {
        Map<Class, Class> map = new HashMap<Class, Class>();
        map.put(Integer.class, String.class);
        return map.get(clazz);
    }

    public static void main(String[] args) {
        Class<Integer> clazz = get(Integer.class);
        System.out.println(clazz);
    }
}

它可以编译并完美运行。想法是在get方法中返回与输入类具有相同类型参数的类。但是由于地图的存在,它被打破了。是的,我知道在运行时会删除类型参数信息,因此,如果没有类型参数,此代码将完全有效。我也知道可以通过指定来修复它,Map<Class<T>, Class<T>>但是事实是,在方法签名中,我具有类型参数,并且它们在编译时没有帮助。

这是对某些概念的滥用吗?

还是Java泛型的缺点?

还是完全正常,我误解了类型参数的概念?

鲁阿赫

原始类型,如ClassMap(相对于Class<...>Map<..., ...>),绕过泛型的检查类型。您甚至可以编写如下内容:

final Class<Integer> whoops = (Class) String.class;

这是类型系统中的一个不幸的弱点。它最初包含在Java 5中(引入了泛型)是为了与以前版本下编写的代码兼容。

在大多数情况下,可以通过避免使用原始类型来避免此缺点。您的编译器应警告您有关它们的信息。

不幸的是,在很多情况下原始类型是不可避免的(由于的特殊类型.getClass();由于我们只能写(例如)Map.class而不能Map<String, String>.class(或Map.<String, String>class);由于擦除和反射等原因);但是很高兴,正如您所指出的,您的情况似乎并非其中之一。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Java泛型-编译器错误

来自分类Dev

泛型和迭代器的Java编译器错误

来自分类Dev

Swift编译器无法解析泛型的递归使用

来自分类Dev

Java:递归泛型编译器错误

来自分类Dev

Maven编译器与Eclipse编译器的泛型有何不同?

来自分类Dev

OCaml变量类型:混淆编译器

来自分类Dev

泛型是否在编译时由编译器删除

来自分类Dev

编译器如何欺骗提供指向封闭类的指针?

来自分类Dev

编译器如何欺骗提供指向封闭类的指针?

来自分类Dev

使用Java泛型并将List作为方法参数的编译器错误并引发泛型异常

来自分类Dev

使用Java泛型并将List作为方法参数的编译器错误并引发泛型异常

来自分类Dev

如何向编译器保证泛型类型将具有一定的属性?

来自分类常见问题

为什么Java编译器在构造函数实例化中无法跟踪泛型类型?

来自分类Dev

为什么C#编译器不能从函数签名中推断泛型委托?

来自分类Dev

Eclipse编译器和Javac之间的差异-枚举,接口和泛型

来自分类Dev

使用泛型时,javac编译器会为每种类型创建不同的类吗?

来自分类Dev

泛型和lambdas-Javac和Eclipse编译器中的不同行为

来自分类Dev

实现Ordered [A [B]]的Scala泛型给出了奇怪的编译器错误

来自分类Dev

为什么Java编译器失去构造函数实例化轨道泛型类型的?

来自分类Dev

条件类型添加了额外的泛型编译器错误

来自分类Dev

为什么运算符<对于Java泛型有编译器错误?

来自分类Dev

保存ArrayLists时由泛型引起的Java编译器警告

来自分类Dev

为何编译器将泛型转换为原始类型?

来自分类Dev

使用泛型时,javac编译器会为每种类型创建不同的类吗?

来自分类Dev

具有可选功能,泛型和类似功能的功能确实满足编译器要求

来自分类Dev

为什么这个java接口定义使用编译器接受的泛型?

来自分类Dev

编译器无法推断泛型类构造函数类型的原因是什么?

来自分类Dev

为什么编译器不允许从 peek 方法返回的泛型不是可选的?

来自分类Dev

使用具有多个边界的泛型时,编译器不会显示编译时错误

Related 相关文章

  1. 1

    Java泛型-编译器错误

  2. 2

    泛型和迭代器的Java编译器错误

  3. 3

    Swift编译器无法解析泛型的递归使用

  4. 4

    Java:递归泛型编译器错误

  5. 5

    Maven编译器与Eclipse编译器的泛型有何不同?

  6. 6

    OCaml变量类型:混淆编译器

  7. 7

    泛型是否在编译时由编译器删除

  8. 8

    编译器如何欺骗提供指向封闭类的指针?

  9. 9

    编译器如何欺骗提供指向封闭类的指针?

  10. 10

    使用Java泛型并将List作为方法参数的编译器错误并引发泛型异常

  11. 11

    使用Java泛型并将List作为方法参数的编译器错误并引发泛型异常

  12. 12

    如何向编译器保证泛型类型将具有一定的属性?

  13. 13

    为什么Java编译器在构造函数实例化中无法跟踪泛型类型?

  14. 14

    为什么C#编译器不能从函数签名中推断泛型委托?

  15. 15

    Eclipse编译器和Javac之间的差异-枚举,接口和泛型

  16. 16

    使用泛型时,javac编译器会为每种类型创建不同的类吗?

  17. 17

    泛型和lambdas-Javac和Eclipse编译器中的不同行为

  18. 18

    实现Ordered [A [B]]的Scala泛型给出了奇怪的编译器错误

  19. 19

    为什么Java编译器失去构造函数实例化轨道泛型类型的?

  20. 20

    条件类型添加了额外的泛型编译器错误

  21. 21

    为什么运算符<对于Java泛型有编译器错误?

  22. 22

    保存ArrayLists时由泛型引起的Java编译器警告

  23. 23

    为何编译器将泛型转换为原始类型?

  24. 24

    使用泛型时,javac编译器会为每种类型创建不同的类吗?

  25. 25

    具有可选功能,泛型和类似功能的功能确实满足编译器要求

  26. 26

    为什么这个java接口定义使用编译器接受的泛型?

  27. 27

    编译器无法推断泛型类构造函数类型的原因是什么?

  28. 28

    为什么编译器不允许从 peek 方法返回的泛型不是可选的?

  29. 29

    使用具有多个边界的泛型时,编译器不会显示编译时错误

热门标签

归档