【问题标题】:Simple Java Generics That Should Show A Compile Error But It Is Not应该显示编译错误但事实并非如此的简单 Java 泛型
【发布时间】:2014-06-04 18:14:39
【问题描述】:

这是一个非常简单的 Java 泛型示例。我的问题是为什么编译器在 intellij 13 和 Java 7 中不显示编译错误而不运行代码,当类在 arraylist 中添加我的 AirUnits 列表时需要实现 Vehicle 的类型而不是实现 AirUnit 的类型需要 HighWay 类的车辆。

车辆:

public interface Vehicle {
     void goForward();
}

空军单位:

public interface AirUnit {
 void fly();
}

Highway 类,它接收一组车辆并运行它们并打印它们的 toString()。

import java.util.ArrayList;

public class HighWay<T extends Vehicle> {

    private ArrayList<T> vehicles;

    public HighWay(ArrayList<T> vehiclesOnTheRoad){
        this.vehicles = vehiclesOnTheRoad;
    }


    public void moveTheVehicles(){
        for(T vehicle: vehicles){
            System.out.println(vehicle);
        }
    }
}

客户

import java.util.ArrayList;

            public class Client {

                public static void  main(String[] args) {
                    Vehicle car = new Car();
                    Vehicle bike = new Bike();
                    AirUnit plane = new Plane();

                    ArrayList<Vehicle> vehicles = new ArrayList();
                    ArrayList<AirUnit> airUnites = new ArrayList();
                    airUnites.add(plane);

                    vehicles.add(car);
                    vehicles.add(bike);


                    // should show compile error because HighWay is expecting something
                    // that implements Vehicle but it is now showing any errors
                    // until I run the app and it breaks in the loop.
                    HighWay<Vehicle> highWay = new HighWay(airUnites);
                    highWay.moveTheVehicles();
                }
            }

【问题讨论】:

标签: java generics


【解决方案1】:

问题在于,当您声明要实例化的 HighWay 类型时,编译器会测试该类型。如果你告诉它你使用的是什么类型,它会抱怨,例如

HighWay<Car> highWay = new HighWay<> (airUnites);

会导致错误,因为 airUnites 不是汽车列表,或者

HighWay<Plane> highWay = new HighWay<> (airUnites);

也会失败,因为 Plane 没有扩展 Vehicle 所以不匹配您指定的约束。但是因为你没有指定你创建的 HighWay 的类型,它会关闭泛型类型检查。它应该因此产生警告,告诉您应该指定类型,尽管您可能禁用了警告(检查您的 IDE 中的编译器设置以查看是否是这种情况 - 我不确定如何这样做是因为我不使用 IntelliJ)。

【讨论】:

    【解决方案2】:

    这是因为你在声明highWay时没有声明你将使用哪种泛型类型:

    HighWay highWay = new HighWay(airUnites);
    

    这会创建一个非泛型类型,其中所有内容都使用Object,而正确使用它取决于您。最好这样说:

    HighWay<Object> highWay = new HighWay<>(airUnites);
    

    【讨论】:

    • 我试过这个:codeHighWay highWay = new HighWay(airUnites);code 它不会给我错误,但这样做时会出现错误:codeHighWay highWay = new HighWay(airUnites);code
    • @SamTheGoodOne 你需要在两边声明类型参数,例如HighWay&lt;Vehicle&gt; highWay = new HighWay&lt;Vehicle&gt;(airUnites);HighWay&lt;Vehicle&gt; highWay = new HighWay&lt;&gt;(airUnites); 用于 Java 7。
    • 我现在明白了,我确实尝试过,但没有尝试在声明的末尾添加类型。现在我得到一个编译错误。感谢您的来信。
    猜你喜欢
    • 1970-01-01
    • 2016-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 2018-09-22
    • 2012-04-21
    相关资源
    最近更新 更多