这是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();
}
}
答案 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);