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====


你可能感兴趣的:(Java泛型数组)