如何将泛型类型限制为java中的特定类型?

时间:2012-02-11 10:03:54

标签: java generics types

我有一个带有泛型变量的类。我想将该变量限制为一组 类型(如汽车,自行车......)如下所示:

class Garage{
   Class<K> ownerStaff;

   public Garage(Car c){
      this.ownerStaff = c;
   }
   public Garage(Bike b){
      this.ownerStaff = b;
   }
   ...
}

所以“genericVariable”只能是Car,Bike或我想要的任何其他类型,但不是任何东西。我怎么能这样做?

注意: 我想我可以创建一个父类“车辆”,然后以那种方式写出来(如果我错了,请纠正我)

class Garage<K extends Vehicle>{
   Class<K> ownerStaff;

   public Garage(Class<K> c){
      this.ownerStaff = c;
   }
}

但是我不想要父类,并且让我的所有类扩展为“Vehicle”,并且我可能不想输入例如当我实例化“车库”时Garage<Car>

由于

3 个答案:

答案 0 :(得分:3)

你的对象最终必须有某种共同的行为,否则将它们放在同一个Garage中是没有意义的。正如@perelman建议的那样,只需在接口中声明这种常见行为并使用它(没有泛型):

public interface Vehicle {
    // common behavior declared, if any
}

public class Car implements Vehicle {
    // Implementation
}

public class Bike implements Vehicle {
    // Implementation
}

public class Garage {
    Vehicle vehicle;

    public Garage(Vehicle v) {
       vehicle = v;
    }
}

答案 1 :(得分:2)

重读您的问题,我认为您想要的只是让ownerStaff字段属于Class<?>类型。这允许您使用任何Class实例填充它,无论其类型如何。

旧答案:限制泛型类型的唯一方法是使用<K extends Vehicle>,正如您已经说过的那样。这样做的另一个好处是能够在您班级Vehicle的实例上调用所有K方法。

您当然可以对值类型进行instanceof检查,例如,在构造函数中添加if (!(Car.class.isAssignableFrom(c) or Bike.class.isAssignableFrom(c))) throw new IllegalArgumentException("we only accept cars and bikes")。这将是一个非常严格的检查,并阻止该类用户发明自己的车辆类型。

答案 2 :(得分:0)

由于Java没有代数数据类型 - 即你不能说“类型A或类型B”,只能通过常见的超类型来“输入A和B” - 这不是你自然可以做的事情。 / p>

解决此问题的一种方法是使Garage的构造函数为private,并仅为特定类型提供静态工厂方法:

class Garage<K> {
    private Garage<K>(K thing) { this.thing = thing; } // hidden
    private K thing;
    public Garage<Car> newCarGarage(Car c) {
        return new Garage<Car>(c);
    }
    //... similarly for other types you want to be allowed
}