It might help you.
super((Class<L>)(Class<?>)List.class, name);
Note: It shows WARNING but you can suppress it using @SuppressWarnings("unchecked")
For more info have a look at Class object of generic class (java)
题
Please consider the following 3 Java classes:
Super class:
public abstract class Column<T>
{
private final Class<T> type;
private final String name;
public Column(Class<T> type, String name)
{
this.type = type;
this.name = name;
}
public Class<T> getType()
{
return type;
}
// ...
}
Working subclass:
public class FloatColumn extends Column<Float>
{
public FloatColumn(String name)
{
super(Float.class, name);
}
// ...
}
Problematic subclass:
public class ListColumn<L extends List<T>, T> extends Column<L>
{
public ListColumn(String name)
{
super((Class<L>) List.class, name);
}
// ...
}
The problematic subclass (ListColumn
) compiles fine in Eclipse, with Java compiler compliance set to 1.6. However, when compiled through Maven (using the JDK compiler, with source and target set to 1.6), I get an Inconvertible types
error at the super()
call in the ListColumn
constructor.
Edit: Eclipse does warn about this line (Type safety: Unchecked cast from Class<List> to Class<L>
).
I know that Eclipse does not use the JDL compiler, and apparently the compiler it does use is less strict than the JDK one.
However, my question is how can I make this code work on the 1.6 JDK compiler.
In other words, how can a I call the super constructor with an argument that conforms to the expected Class<L>
type where L
is restricted to extends List<T>
.
Preferably I only want to make changes in the ListColumn
constructor, not in the Column
class.
解决方案
It might help you.
super((Class<L>)(Class<?>)List.class, name);
Note: It shows WARNING but you can suppress it using @SuppressWarnings("unchecked")
For more info have a look at Class object of generic class (java)
其他提示
Assume I instantiate your class as follows:
ListColumn<ArrayList<String>, String> listColumn = new ListColumn<ArrayList<String>, String>("column");
Now, your code will try to cast List.class
to a Class<ArrayList>
which is not the case.
You can make use of covariance in your Column
class if you want to allow clients to use subtypes of your T
generic type. For instance, changing the Column
constructor to:
public Column(Class<? extends T> type, String name)
would allow you to call super in your ListColumn
without any cast, since any subtype of List
would now be allowed, but in a type safe manner.
As for tricking the compiler to accept any sort of generics cast with a mere warning, you can use the most dirty "double cast" trick that simply eliminates generics so the compiler won't catch up with your code anymore:
List<Integer> l = new ArrayList<Integer>();
List<String> s = (List<String>) (List) l;
But is that really what you want ?