java - Java 中的泛型和子类型问题

标签 java generics types programming-languages

<分区>

首先,由于 java 有一个严格的类型系统,所以在编译时检查程序的类型正确性,并在执行前将类加载到字节码 validator 时检查程序的字节码。

虽然泛型的引入拓宽了 Java 类型系统的潜力,但是由于 java 有子类型,所以在上面的例子中出现了很多问题:

 String [] a ={"Hello"};
        Object [] b= a;
        b[0]=  false;
        String s=a[0];

        System.out.println(s);

在上面的示例中,我们使用 String 类是 Object 的子类。 我的问题是编译器不对上述程序发出任何警告的原因是什么。当我尝试运行它时(当然)抛出异常。 上面的程序在 java 实现中还有什么问题/后果(我的意思是有没有明显的问题??)。

最佳答案

Java 中的数组是协变的,即。 String[] 可以传递给需要 Object[] 的对象。这就是编译器不会阻止您将 boolean 值插入字符串数组的原因。

为了提供协变性同时也提供运行时保护,Java 工程师设计了数组,以便在编译时添加一个标记,用它的类型标记数组。即使我们可以在编译时添加 boolean 值,String[] 上的类型阻止我们在运行时添加 boolean 值 - 这就是您可能遇到的触发 ArrayStoreException 的原因当您运行代码时。

在 Java 中,这是在拥有协变数组和捕获向数组添加错误内容的步骤之间的权衡。这种权衡正是某些语言(如 Scala)选择不使用协变数组的原因。

创建通用数组是可能的,但并不简单,并且存在一些类型危险,因此这些方法适用于特定用例 - Josh Bloch 的 Effective Java 讨论了这些。

可以说,使用通用列表而不是数组会更好,因为这样您就可以在编译时发现问题。

关于java - Java 中的泛型和子类型问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39378219/

相关文章:

Python - 仅一种类型的集合

java - 在 Google App Engine 上调试编译和部署的 JSP

java - 需要关于如何在面板上方插入小文本短语的想法

c# 重载具有不同参数约束的泛型函数

java - 使用通配符创建新的通用对象

java - 调用对可能实现该接口(interface)的对象进行接口(interface)约束的泛型方法

generics - 这种构造导致代码不像类型注释所指示的那么通用

php - 在 PHP 中指定类的对象类型的方法

java - Spring Boot多个数据库: No qualifying bean of type EntityManagerFactoryBuilder

java - 在 Google Maps Android API 中管理我自己的路径的最佳方式