YAJGCQ又一个Java泛型与收藏Q.

时间:2012-02-16 17:12:24

标签: java generics collections

在我的背后使用可靠的C ++,一些Java概念并非100%清晰。

List<SomeInterface> list = new ArrayList<SomeImplementation>; 

这是100%明确无需解释 - 但它有后果......

interface Drivable {...}
class Car implements Drivable  {...}
class Bike implements Drivable  {...}
class Skateboard implements Drivable  {...}

class MyGarage{
List<Driveable> myRides;

public void addRides( List<Driveable> rideList ){...} 

List<Car>无法调用。但是我可以通过以下方式将汽车添加到myRides:

public void addCars( List<Car> carList ){
myRides.addAll( new List<Driveable>( carList ) );

Q1:这是个好主意吗?

我真的想要像第一个功能一样工作。通过执行与C ++ const&相对应的内容并将副本添加到myRides中,我认为carList将受到保护,以防止非法访问。我希望将final作为一个函数参数添加起来。

Q2:有没有办法让完全可调用的addRides(List<Driveable> rideList)工作?

超载(List<Car> List<Bike> etc)也不合法。

是的,我可以通过添加单独的函数addBikes() addCars etc来完成这项工作,或者我可以在每个调用点执行new List<Drivable>。但我希望能有更时尚的东西。

问题3:有任何建议吗?

非常感谢! 亚当

5 个答案:

答案 0 :(得分:4)

您的 addRides 方法应如下所示:

public void addRides(Collection<? extends Drivable> c)

如果对泛型使用有疑问,请在 java.util 中查找集合接口,它们有很多示例,您想要做的与 {{3}相同确实。

答案 1 :(得分:0)

A1。为了获得更好的保护,您可以使用Collections.unmodifiableList()包装列表。

A2。您需要public void addRides( List<? extends Driveable> rideList ){...},因为rideList可以包含任何扩展可驱动的内容。

A3。不客气!

答案 2 :(得分:0)

对通用参数使用通配符类型。宣言将是

addRides(List<? extends Driveable> list);

这会接受Car,Skateboard,Bike或任何其他Driveable的列表,并且会正确编译。

答案 3 :(得分:0)

您可以通过对方法进行参数化来实现此目的:

public class MyGarage{
    public static void main(String[] args) {
        MyGarage garage = new MyGarage();
        garage.addRides(new ArrayList<Car>(4));
        garage.addRides(new ArrayList<Bike>(4));
    }

    List<Driveable> myRides;

    public <T extends Driveable> void addRides( List<T> rideList ){
        // ...
    } 
}

这基本上声明您的方法将接受任何对象列表T,使得T从Driveable扩展。我建议从生产者和消费者的角度阅读描述Java Generics的this excellent SO post

答案 4 :(得分:0)

你没有问过的问题应该是第一行代码

List<SomeInterface> list = new ArrayList<SomeImplementation>; 
  

为什么不编译?

原因不一样是您需要public void addRides( List<? extends Driveable> rideList )

的原因