应该显示编译错误的简单Java泛型但不是

时间:2014-04-20 16:03:49

标签: java generics

这是Java Generics的一个非常简单的例子。我的问题是,为什么编译器在没有运行代码的情况下显示编译错误在intellij 13中使用Java 7,当类期望实现Vehicle的类型而不是在arraylist中添加我的AirUnit列表时实现AirUnit的类型期待HighWay Class的车辆。

车辆:

public interface Vehicle {
     void goForward();
}

AirUnit:

public interface AirUnit {
 void fly();
}

高速公路类,它接收一系列车辆并运行它们并打印它们的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();
                }
            }

2 个答案:

答案 0 :(得分:1)

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

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

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

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

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

答案 1 :(得分:0)

这是因为您在宣布highWay时未声明将使用哪种通用类型:

HighWay highWay = new HighWay(airUnites);

这会创建一个非泛型类型,其中所有内容都使用Object,并且您可以正确使用它。最好的想法是:

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