Due to the implementation of Java generics, you can't have code like this:
public class GenSet {
private E a[];
public GenSet() {
a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array creation
}
}
How can I implement this while maintaining type safety?
I saw a solution on the Java forums that goes like this:
import java.lang.reflect.Array;
class Stack {
public Stack(Class clazz, int capacity) {
array = (T[])Array.newInstance(clazz, capacity);
}
private final T[] array;
}
But I really don't get what's going on.
Answer
I have to ask a question in return: is your GenSet "checked" or "unchecked"?
What does that mean?
Checked: strong typing.
GenSetknows explicitly what type of objects it contains (i.e. its constructor was explicitly called with aClassargument, and methods will throw an exception when they are passed arguments that are not of typeE. SeeCollections.checkedCollection.-> in that case, you should write:
public class GenSet{
private E[] a;
public GenSet(Classc, int s) {
// Use Array native method to create array
// of a type only known at run time
@SuppressWarnings("unchecked")
final E[] a = (E[]) Array.newInstance(c, s);
this.a = a;
}
E get(int i) {
return a[i];
}
}Unchecked: weak typing. No type checking is actually done on any of the objects passed as argument.
-> in that case, you should write
public class GenSet{
private Object[] a;
public GenSet(int s) {
a = new Object[s];
}
E get(int i) {
@SuppressWarnings("unchecked")
final E e = (E) a[i];
return e;
}
}Note that the component type of the array should be the erasure of the type parameter:
public class GenSet{ // E has an upper bound of Foo
private Foo[] a; // E erases to Foo, so use Foo[]
public GenSet(int s) {
a = new Foo[s];
}
...
}
All of this results from a known, and deliberate, weakness of generics in Java: it was implemented using erasure, so "generic" classes don't know what type argument they were created with at run time, and therefore can not provide type-safety unless some explicit mechanism (type-checking) is implemented.
No comments:
Post a Comment