0

Possible Duplicate:
get type of a generic parameter in java with reflection

Hi I read here about solutions to get instances of generic types. I think my my problem differs a bit, so I break it down for easyness. Lets assume I have three classes:

public class Car (){
    public int velocity;
    public String name;
    public Car(int velocity, String name){
        this.velocity = velocity;
        this.name = name;
    }
}

public class ColoredCar extends Car(){
    public String color;
    //setters and getters for color, same Constructor....
}
public class DrivenCar extends ColoredCar(){
    public Driver driver;
    //setters and getters, same Constructor
}

Now I extended the ArrayList like:

public class Cars<CAR extends Car> extends ArrayList<CAR>{

    public String[] getColors(){
        String[] ret = new String[this.size()];
        int count = 0;
        for(CAR c: this){
            ret[count++] = c.getColor();
        }
        return ret;
    }
    //some more.....
}

ok, If I need to create a class which extends Cars and in its Constructor I know already they are 10 Objects of CAR, what do I have as possibility? I know I can create Car Objects with velocity and name, which I have.

Edit: lets say I have a function in my Cars:

public CAR createCar(int velocity, String name){
    return (CAR)new Car(velocity, name); 
}

and at Runtime Cars is defined as Cars, do I get an error, because I can't cast a Car to a DrivenCar?

Community
  • 1
  • 1
Rafael T
  • 15,401
  • 15
  • 83
  • 144
  • to create Objects of the type CAR which is passed as generic – Rafael T Sep 13 '11 at 00:09
  • 2
    In that case, your question is the same as all the questions about performing `new T` (or the equivalent) where `T` is the generic parameter. The answer is: you can't. (At least, not without already having an instance of `T`.) – Oliver Charlesworth Sep 13 '11 at 00:10
  • is there a problem when I Cast a Car to CAR, even at Runtime CAR is a DrivenCar? – Rafael T Sep 13 '11 at 00:19
  • Please edit your question to include a code example of what you mean. – Oliver Charlesworth Sep 13 '11 at 00:21
  • @Rafael: Bear in mind that an `ArrayList` is not the same thing as an `ArrayList`. `ArrayList` can hold only objects, **all of the same type**, that are all of some **specific** subclass of `Car`. `ArrayList` can hold objects of any type that is a subclass of `Car`. So it doesn't make sense to have a `getColors()` method on your `Cars` class, because if I had an instance of `Cars`, then it **cannot** contain any `ColoredCar` instances. – Daniel Pryden Sep 13 '11 at 00:28
  • @Oli edited my question. Sorry for the missing extends in DrivenCar – Rafael T Sep 13 '11 at 10:19

1 Answers1

1

If you are asking about how to construct an object T at runtime, you can always pass in T.class, and then use its newInstance() method to create objects of that type. If you are asking about how to initialize your container class with the list of T objects, then...

You could define a constructor that uses super to invoke a parent constructor and pass in the items (converted to a collection, first), or you could define your own constructor that simply calls the add method to add your ten cars. However, this is a serious misuse of the inheritance pattern.

Inheritance is NOT for code reuse. It is for variation (i.e. multiple different possible implementations of the same interface). For code reuse, containment is almost always a better paradigm. I.e.:

class Cars<CAR> {
    private List<CAR> cars = new ArrayList<CAR>();

    // ...

    public Iterable<String> getColors() {
       return Iterables.transform(cars, getCarToColorTransform());
    }

    // Expose other methods of List<CAR>, but ONLY the ones you need.
}
Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
  • looks like an Adapter-Pattern. This is exactly what I have done with Cars, but for easyness I posted it here like I inherited ArrayList. – Rafael T Sep 13 '11 at 10:22