Java中泛型创建数组的总结

开发 后端
在java中,不能通过直接通过T[] tarr=new T[10]的方式来创建数组,最简单的方式便是通过Array.newInstance(Class<t>type,int size)的方式来创建数组例如下面的程序。

在java中,不能通过直接通过T[] tarr=new T[10]的方式来创建数组,最简单的方式便是通过Array.newInstance(Class<t>type,int size)的方式来创建数组例如下面的程序。

public class ArrayMaker<T> {    
    private Class<T> type;    
    
    public ArrayMaker(Class<T> type) {    
        this.type = type;    
    }    
    
    @SuppressWarnings("unchecked")    
    T[] createArray(int size) {    
        return (T[]) Array.newInstance(type, size);    
    }    
    
    List<T> createList() {    
        return new ArrayList<T>();    
    }    
    
    /**   
     * @param args   
     */    
    public static void main(String[] args) {    
        /*   
         * Even though kind is stored as Class<T> , erasure means that it is actually just being stored as a Class, with   
         * no parameter. So, when you do some thing with it, as in creating an array, Array.newInstance( ) doesn’t   
         * actually have the type information that’s implied in kind; so it cannot produce the specific result, wh ich   
         * must therefore be cast, which produces a warning that you cannot satisfy.   
         */    
        ArrayMaker<Type> am2 = new ArrayMaker<Type>(Type.class);    
        System.out.println(Arrays.asList(am2.createArray(10)));    
        System.out.println(Arrays.asList(am2.createList()));    
    }    
    
}    
    
class Type {    
    @Override    
    public String toString() {    
        return "type";    
    }    
}   
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.

上面的这个例子比较简单,但是如果你有接触过泛型数组,你便对他的复杂度有一定的了解,由于创建泛型数组比较复杂,所以在实际的应用过程中一般会选择List的对泛型进行存储,如果实在需要使用泛型数组,则需要注意数组的在运行时的类型,think in java这本书中,对泛型数组的处理通过四个小程序对其进行了比较完整的描述。

程序一:这个程序主要说明了,在使用泛型数组中容易出现的问题,由于书中对于程序的说明比较详细,所以只对程序做引用。

class Generic<T> {    
}    
    
public class ArrayofGeneric {    
    public static void main(String[] args) {    
        Generic<Integer>[] genArr;    
        /*   
         * will throw ClassCastException :The problem is that arrays keep track of their actual type, and that type is   
         * established at the point of creation of the array. So even though genArr has been cast to a Generic < Integer   
         * >[] , that information only exists at compile time (and without the @SuppressWarnings annotation, you’d get a   
         * warning for that cast). At run time, it’s still an array of Object, and that causes problems.   
         */    
        // genArr = (Generic<Integer>[]) new Object[] {};    
        /* can not create a generic of array */    
        // genArr=new Generic<Integer>[2];    
        genArr = (Generic<Integer>[]) new Generic[2];    
        System.out.println(genArr);    
    }    
}  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

程序二:这个程序主要是说明在程序的执行过程中,泛型数组的类型信息会被擦除,且在运行的过程中数组的类型有且仅有Object[],如果我们强制转换成T[]类型的话,虽然在编译的时候不会有异常产生,但是运行时会有ClassCastException抛出。

/**   
 *    
 * Because of erasure, the runtime type of the array can only be Object[]. If we immediately cast it to T[], then at   
 * compile time the actual type of the array is lost, and the compiler may miss out on some potential error checks.   
 *    
 *    
 *    
 * archive $ProjectName: $   
 *    
 * @author Admin   
 *    
 * @version $Revision: $ $Name: $   
 */    
public class ArrayOfGeneric2<T> {    
    public T[] ts;    
    
    public ArrayOfGeneric2(int size) {    
        ts = (T[]) new Object[size];    
    }    
    
    public T get(int index) {    
        return ts[index];    
    }    
    
    public T[] rep() {    
        return ts;    
    }    
    
    public void set(int index, T t) {    
        ts[index] = t;    
    }    
    
    public static void main(String[] args) {    
        ArrayOfGeneric2<String> aog2 = new ArrayOfGeneric2<String>(10);    
        Object[] objs = aog2.rep();    
        System.out.println(objs);    
        /* will throw ClassCastException */    
       // String[] strs = aog2.rep();    
        // System.out.println(strs);    
    }    
    
}   
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.

程序三:主要说明在对象中通过用Object[]来保存数据,则生成对象是,可以对其持有的对象在T和object之间进行转换,但是当设计到数组的转换时,还是会报ClassCastException

/**   
 *    
 * Initially, this doesn’t look very different compare with ArrayOfGeneric2.java , just that the cast has been moved.   
 * Without the ©SuppressWarnings annotations, you will still get "unchecked" warnings. However, the internal   
 * representation is now Object[] rather than T[]. When get( ) is called, it casts the object to T, which is in fact the   
 * correct type, so that is safe. However, if you call rep( ) , it again attempts to cast the Object[] to a T[], which   
 * is still incorrect, and produces a warning at compile time and an exception at run time. Thus there’s no way to   
 * subvert the type of the underlying array, which can only be Object[]. The advantage of treating array internally as   
 * Object[] instead of T[] is that it’s less likely that you’ll forget the runtime type of the array and accidentally   
 * introduce a bug (although the majority, and perhaps all, of such bugs would be rapidly detected at run time)   
 *    
 *    
 *    
 * archive $ProjectName: $   
 *    
 * @author Admin   
 *    
 * @version $Revision: $ $Name: $   
 */    
public class ArrayOfGeneric3<T> {    
    Object[] ts;    
    
    public ArrayOfGeneric3(int size) {    
        ts = new Object[size];    
    }    
    
    public T get(int index) {    
        return (T) ts[index];    
    }    
    
    public T[] rep() {    
        return (T[]) ts;    
    }    
    
    public void set(int index, T t) {    
        ts[index] = t;    
    }    
    
    public static void main(String[] args) {    
        ArrayOfGeneric3<Integer> aog2 = new ArrayOfGeneric3<Integer>(10);    
        Object[] objs = aog2.rep();    
        for (int i = 0; i < 10; i++) {    
            aog2.set(i, i);    
            System.out.println(aog2.get(i));    
        }    
            Integer[] strs = aog2.rep();    
            System.out.println(strs);    
    }    
}   
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.

程序四:是对泛型数组相对而言比较***的解决方案

/**   
 *    
 * The type token Class<T> is passed into the constructor in order to recover from the erasure, so that we can create   
 * the actual type of array that we need, although the warning from the cast must be suppressed with @SuppressWarnings.   
 * Once we do get the actual type, we can return it and get the desired results, as you see in main( ). The runtime type   
 * of the array is the exact type T[].   
 *    
 * @author Admin   
 *    
 * @version $Revision: $ $Name: $   
 */    
public class ArrayOfGeneric4<T> {    
    
    T[] ts;    
    
    public ArrayOfGeneric4(Class<T> type, int size) {    
        /* to solution array of generic key code! */    
        ts = (T[]) Array.newInstance(type, size);    
    }    
    
    public T get(int index) {    
        return ts[index];    
    }    
    
    public T[] rep() {    
        return ts;    
    }    
    
    public void set(int index, T t) {    
        ts[index] = t;    
    }    
    
    public static void main(String[] args) {    
        ArrayOfGeneric4<Integer> aog2 = new ArrayOfGeneric4<Integer>(Integer.class10);    
        Object[] objs = aog2.rep();    
        for (int i = 0; i < 10; i++) {    
            aog2.set(i, i);    
            System.out.println(aog2.get(i));    
        }    
        try {    
            Integer[] strs = aog2.rep();    
            System.out.println("user Array.newInstance to create generci of array was successful!!!!! ");    
        } catch (Exception ex) {    
            ex.printStackTrace();    
        }    
    }    
}   
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.

泛型这一章节的内容从擦除开始,觉得都是非常的难懂,如果哪位同志有比较好的建议,希望能不惜指教!

原文链接:http://blog.csdn.net/sun7545526/article/details/7262486

【编辑推荐】

  1. Java Socket重要参数讲解
  2. Java的辉煌还能延续多久?
  3. 深入理解Java对象序列化
  4. 对于Java类加载过程中的顺序问题探究
  5. Java多线程之消费者生产者模式
责任编辑:林师授 来源: sun7545526的博客
相关推荐

2009-09-25 10:03:51

Java泛型

2009-08-25 14:03:17

2009-03-17 16:22:13

Java泛型接口

2009-08-24 15:38:21

C# 泛型数组

2009-10-10 09:27:42

Java泛型通用方法

2021-06-17 06:51:32

Java泛型Java编程

2017-03-06 16:51:52

Java泛型实现

2015-11-02 09:36:59

Javasuperextends

2021-09-29 18:17:30

Go泛型语言

2024-04-23 08:23:36

TypeScript泛型Generics

2021-12-30 19:34:15

Java泛型JDK

2011-06-03 08:49:54

Java

2009-06-16 11:32:00

Java泛型

2020-10-26 14:01:22

Java泛型

2009-06-11 17:31:27

Java泛型

2023-11-08 08:27:30

泛型Java

2021-07-09 06:11:37

Java泛型Object类型

2009-03-26 10:52:44

J2SE泛型集合

2009-08-24 16:39:19

C# 泛型应用

2023-10-07 00:01:02

Java函数
点赞
收藏

51CTO技术栈公众号