Java泛型数组
泛型数组
在java中,不能通过直接通过T[] tarr=new T[10]的方式来创建数组,最简单的方式便是通过Array.newInstance(Class<T> type,int size)的方式来创建数组。
如下面这段程序:
package hash;
import java.lang.reflect.Array;
/**
* 数组的工具
*
* @author David Day
*/
public class ArrayUtils {
/**
* 根据数组类型的class创建对应类型的数组
*
* @param <T> 目标类型
* @param clazz
* @param length 数组长度
* @return
*/
public static <T> T[] newArrayByArrayClass(Class<T[]> clazz, int length) {
return (T[]) Array.newInstance(clazz.getComponentType(), length);
}
/**
* 根据普通类型的class创建数组
*
* @param <T> 目标类型
* @param clazz
* @param length 数组长度
* @return
*/
public static <T> T[] newArrayByClass(Class<T> clazz, int length) {
return (T[]) Array.newInstance(clazz, length);
}
public static void main(String[] args) {
// 判断一个Class是否是数组类型,可以用Class实例的isArray方法。
String[] byArray = newArrayByArrayClass(String[].class, 10);
String[] byOne = newArrayByClass(String.class, 10);
System.out.println(byArray.getClass().isArray());
System.out.println(byOne.getClass().isArray());
}
}
泛型数组的类型擦除
package sort;
/**
* Created with IntelliJ IDEA.
* User: ASUS
* Date: 14-9-10
* Time: 下午10:34
* To change this template use File | Settings | File Templates.
*/
public class People implements Comparable<People> {
public int age;
public String name;
public People(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof People)) return false;
People people = (People) o;
if (age != people.age) return false;
if (!name.equals(people.name)) return false;
return true;
}
@Override
public int hashCode() {
int result = age;
result = 31 * result + name.hashCode();
return result;
}
/**
* 这个方法定义排序的规则
*
* @param o
* @return
*/
@Override
public int compareTo(People o) {
return this.age - o.getAge();
}
@Override
public String toString() {
return "People{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
看下面这个程序:
package hash;
import sort.People;
/**
* Created with IntelliJ IDEA.
* User: ASUS
* Date: 14-9-12
* Time: 下午5:12
* To change this template use File | Settings | File Templates.
*/
public class GenericArray<T> {
private final T[] items;
public GenericArray(int size) {
items = (T[]) new Object[size];
}
public void put(int index, T t) {
items[index] = t;
}
public T get(int index) {
return items[index];
}
public T[] getItems() {
return items;
}
public static void main(String args[]) {
GenericArray<People> peopleGenericArray = new GenericArray<People>(5);
peopleGenericArray.put(0, new People(12, "12323"));
peopleGenericArray.put(1, new People(12, "12323"));
peopleGenericArray.put(2, new People(12, "12323"));
peopleGenericArray.put(3, new People(12, "12323"));
People p = peopleGenericArray.get(0);
System.out.println(p);
System.out.println("sddddddddddddddd");
try {
People[] peoples = peopleGenericArray.getItems(); //这行代码会出现ClassCastException异常
for (People people : peoples) {
System.out.println(people);
}
} catch (Exception e) {
e.printStackTrace();
}
try {
Object[] objects = peopleGenericArray.getItems();
for (Object object : objects) {
System.out.println(object);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
泛型数组的类型信息会被擦除,且在运行的过程中数组的类型有且仅有Object[],如果我们强制转换成T[]类型的话,虽然在编译的时候不会有异常产生,但是运行时会有ClassCastException抛出。
运行结果:
People{age=12, name='12323'}
sddddddddddddddd
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lsort.People;
at hash.GenericArray.main(GenericArray.java:43)
People{age=12, name='12323'}
People{age=12, name='12323'}
People{age=12, name='12323'}
People{age=12, name='12323'}
null
分析结果:
Object[] objects = peopleGenericArray.getItems();
这行代码是正确的,因为在程序运行过程中仅存在这Object[]类型的数组,所以类型转换过程中要使用Object[]。。。而不能使用People[],虽然编译过程不会出现错误。。
总结:在泛型数组中发生的强制类型转换
在上面这段程序中,因为泛型的原因,当取得数组中每个元素时People p = peopleGenericArray.get(0),不需要显式进行向下的强制类型转换。也是由于泛型的原因,当取得数组对象时,也没有显式的向下强制类型转换,但为什么运行会出现类型匹配异常,是因为没有首先向上类型转换。结合下面这段程序可以更好体会到其中的道理。
Java强制类型转换
package hash;
import org.junit.Test;
import sort.People;
/**
* Created with IntelliJ IDEA.
* User: ASUS
* Date: 14-9-12
* Time: 下午7:45
* To change this template use File | Settings | File Templates.
*/
public class TestClassCast {
@Test
public void test() {
Object obj = new Object();
People people = (People) obj;//强制类型转换,这里会发生异常ClassCastException
/**
* java.lang.ClassCastException: java.lang.Object cannot be cast to sort.People
*/
}
@Test
public void test8978() {
Object obj = new People(12, "liu"); //自动向上转型
People pp = (People) obj; //强制类型转换-向下转型
System.out.println(pp.toString()); //People{age=12, name='liu'}
}
@Test
public void test89() {
Object[] objects = new People[3];
objects[0] = new People(12, "sdsd");
objects[1] = new People(12, "sdsd");
objects[2] = new People(12, "sdsd");
People[] peoples = (People[]) objects; //强制类型转换
System.out.println(peoples); //[Lsort.People;@66cd51c3
}
@Test
public void test232323() {
Object[] objects = new Object[19];
People[] peoples = (People[]) objects;
/**
* java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lsort.People;
*/
}
}
通过上面的代码,我们可以总结:向下的强制类型转换必须先有(先经过)自动的向上类型转换,否则会发生类型匹配异常错误。
关于强制类型转换:http://www.cnblogs.com/chenssy/p/3393160.html
==========END==========