Reputation: 43
I am trying to implement parameterized class in Java with enum as a type parameter. Everything works fine, except, if you look at the code below, there is that anonymous class Car.Creator
with parameter K
. But of course, instead of K
, there should be CarObject<T>
, but it's not that easy. If I put CarObject<T>
in K
's place, then I got syntax error. Could someone explain if something like this is possible and maybe provide with some code sample.
public class CarObject<T extends Enum<T>>
{
public Map<T, String> values;
private Class<T> typeClass;
public CarObject(Class<T> clazz)
{
typeClass = clazz;
values = new EnumMap<T,String>(typeClass);
}
public static final Car.Creator<K> Creator = new Car.Creator<K>()
{
public K create()
{
return new K();
}
public K[] newArray(int size)
{
return new K[size];
}
}
}
I can give you an example from official Android documentation(look at the code in 'Class Overview') where this works perfectly fine. I think there is some magic going on under the hood in Android. I'm trying to do exactly the same thing - implement Parcelable interface. I just made up this example without implements Parcelable
and other stuff, because I though maybe it's just a syntax sugar :).
Upvotes: 0
Views: 1604
Reputation: 310875
Make the method non-static as per the compiler message, but you have several other major design problems anyway. create() needs a clazz from somewhere, and you can't return generic arrays.
EDIT I don't normally post code solutions but you seem pretty confused.
public class CarObject<T extends Enum<T>>
{
public Map<T, String> values;
private Class<T> typeClass;
public CarObject(Class<T> clazz)
{
typeClass = clazz;
values = new EnumMap<T, String>(typeClass);
}
public final Car.Creator<CarObject<T>> Creator = new Car.Creator<CarObject<T>>()
{
@Override
public CarObject<T> create()
{
return new CarObject<T>(typeClass);
}
@Override
public CarObject<T>[] newArray(int size)
{
return new CarObject[size];
}
};
}
Upvotes: 1
Reputation: 60947
I'm no Android expert, but I'm pretty sure there's nothing magic about how this is happening in Android. I think you're just confused about the relationship between generic type arguments and statics.
Generic type arguments (like T
in your example) belong to the instances of the class, not to the class itself.
Static members (like Creator
in your example) belong to the class itself, not to the instances of the class.
The fact that Creator
is an anonymous inner class implementing a generic interface is a bit of a red herring here. The issue is simply that, regardless of what Creator
is, as long as it is static
, it can't access the type T
.
Upvotes: 0
Reputation: 51030
Look at the following statement -
public static final Car.Creator<K> Creator = new Car.Creator<K>() {
public K create() {
return new K();
}
public K[] newArray(int size) {
return new K[size];
}
}; // <------ missing a semicolon here
Looks like you have a generic class Creator defined as static inner class in the class Car. And, here your trying to use it and instantiate it, so can not use K here unless it's a class or an interface defined somewhere.
I think the following example explains what I mean -
// you are not defining a class here so no parameter instead use a real class
public static final List<K> list = new List<K>() { /*....*/ };
Upvotes: 1