我现在遇到一个问题,就是想在定义了泛型的类中,构建一个泛型类的数组。但是在泛型类中,是不可以直接new泛型数组的(尽管可以通过先构建一个Object数组然后在强转成泛型数组)。所以我想通过在泛型类中,获取从创建对象的地方传来的泛型的class对象,然后通过Array.newInstance(Class<?> componentType, int length)这个方法,来动态创建数组。比较简单的办法,是直接在构建对象的时候,传入泛型类的class对象,作为构造参数。但明明我在构造对象的时候,就已经传入了泛型代替AnyType了,却又重复地再传了一次参数,觉得没有必要 。所以我想有没有办法可以直接在定义泛型的类中获取传来的泛型类型。目前我能获得具体的泛型的类型,但还是没想到有什么好的办法可以在定义了泛型的类中,获得传来的泛型类型(尽管那个AnyType本身可以获得。。)求大神给个解决办法。public class MyQueue<AnyType> {
/**
* 队列数组容量
*/
private int capacity;
/**
* 封装的数组
*/
private AnyType[] data; //其他属性略过 // 创建
public MyQueue(Class<AnyType> type,int capacity) {
this.capacity = capacity;
//法一:通过强转数组
//data = (AnyType[]) new Object[capacity];//这样做可以实现需求,但底层毕竟是Object[]类型,
//我想要真正的传入的泛型类型的数组 //法二:通过传入AnyType的clazz对象
// data = getArray(type,capacity); //法三:通过获取传来的泛型类来构建数组,可以少传一个参数。(待解决!!!!)
Class<AnyType> clazz = getGenType();//此处返回的只是AnyType类的class,
//并不是我所要的泛型类的class,不知该如何获得
data = getArray(clazz,capacity);//由于构建的只是AnyType的数组,因此,添加Integer元素会抛异常Exception in
// thread "main" java.lang.ArrayStoreException: java.lang.Integer
clear();
}
@SuppressWarnings("unchecked")
private <E> E[] getArray(Class<E> e,int capacity){
return (E[]) Array.newInstance(e, capacity);
}
//获取传入的泛型类
private Class<AnyType> getGenType(){
Type[] types = getClass().getTypeParameters();
Class<AnyType> clazz = (Class<AnyType>) types[0].getClass();
System.out.println(Arrays.toString(types));
return clazz;
}
//其他方法省略
}测试类:
public class TestQueue { public static void main(String[] args) {
MyQueue<Integer> qu = new MyQueue<>(Integer.class,4);
qu.enqueue(4);
qu.enqueue(6);
qu.enqueue(7);
qu.enqueue(9); qu.traverse();
}
}------------------------------------------------------------------------------
除此之外,还有几个小疑问:
1,在类中获得泛型的具体类型有什么应用吗?比如我在上面那个测试类上获得传入的Integer这个泛型类,但感觉没什么意义啊。。因为我本来就可以直接知道。。
2.在定义泛型的类中,泛型为什么不能直接用来new数组?而通过强转就可以。。(好神奇)
/**
* 队列数组容量
*/
private int capacity;
/**
* 封装的数组
*/
private AnyType[] data; //其他属性略过 // 创建
public MyQueue(Class<AnyType> type,int capacity) {
this.capacity = capacity;
//法一:通过强转数组
//data = (AnyType[]) new Object[capacity];//这样做可以实现需求,但底层毕竟是Object[]类型,
//我想要真正的传入的泛型类型的数组 //法二:通过传入AnyType的clazz对象
// data = getArray(type,capacity); //法三:通过获取传来的泛型类来构建数组,可以少传一个参数。(待解决!!!!)
Class<AnyType> clazz = getGenType();//此处返回的只是AnyType类的class,
//并不是我所要的泛型类的class,不知该如何获得
data = getArray(clazz,capacity);//由于构建的只是AnyType的数组,因此,添加Integer元素会抛异常Exception in
// thread "main" java.lang.ArrayStoreException: java.lang.Integer
clear();
}
@SuppressWarnings("unchecked")
private <E> E[] getArray(Class<E> e,int capacity){
return (E[]) Array.newInstance(e, capacity);
}
//获取传入的泛型类
private Class<AnyType> getGenType(){
Type[] types = getClass().getTypeParameters();
Class<AnyType> clazz = (Class<AnyType>) types[0].getClass();
System.out.println(Arrays.toString(types));
return clazz;
}
//其他方法省略
}测试类:
public class TestQueue { public static void main(String[] args) {
MyQueue<Integer> qu = new MyQueue<>(Integer.class,4);
qu.enqueue(4);
qu.enqueue(6);
qu.enqueue(7);
qu.enqueue(9); qu.traverse();
}
}------------------------------------------------------------------------------
除此之外,还有几个小疑问:
1,在类中获得泛型的具体类型有什么应用吗?比如我在上面那个测试类上获得传入的Integer这个泛型类,但感觉没什么意义啊。。因为我本来就可以直接知道。。
2.在定义泛型的类中,泛型为什么不能直接用来new数组?而通过强转就可以。。(好神奇)
.getGenericSuperclass()).getActualTypeArguments()[0];
泛型的应用多用于,从几个类中抽取出来的公共方法中!这些方法唯一的不同就是对象的类型!比如basedao,baseaction这些类! 简单类型基本不会用,一般是对象的类型!
泛型的类型要在运行的时候才知道, 在这之前jvm是不知道需要创建什么类型的数组,也没办法知道创建何种实例, 所以没有办法直接使用new E() 或者new E[n];实际构建Object数组只是向上转型而已, 内存中的实际类型依然是泛型指定的明确类型.
public class MyQueue<E> {
private int capacity;
private Object[] datas;
private int size; public MyQueue() {
this(10);
} public MyQueue(int capacity) {
if (capacity > 0) {
this.capacity = capacity;
} else {
this.capacity = 10;
}
datas = new Object[this.capacity];
}
private E element(int index) {
return (E) datas[index];
}
public void add(E e) {
// TODO 逻辑部分省略
datas[size++] = e;
} public E popFirst() {
if (size == 0) return null;
E e = element(0);
System.arraycopy(datas, 1, datas, 0, size - 1);
datas[size - 1] = null;
size--;
return e;
} public E popLast() {
if (size == 0) return null;
E e = element(size - 1);
datas[size - 1] = null;
size--;
return e;
} public int size() {
return size;
} @Override
public String toString() {
return Arrays.toString(Arrays.copyOf(datas, size));
} public static void main(String[] args) {
MyQueue<Integer> queue = new MyQueue<>();
queue.add(3);
queue.add(5);
queue.add(9);
System.out.println("queue size: " + queue.size());
System.out.println(queue);
Integer first = queue.popFirst();
System.out.println("first data: " + first);
System.out.println(queue);
Integer last = queue.popLast();
System.out.println("last data: " + last);
System.out.println(queue);
System.out.println("queue size: " + queue.size());
}
}
当然,为了通用性, 最好实现java.util.Queue<E>