我们先来看一段代码:

public static void main(String[] args) {
        Collection collection = new ArrayList<>();
        collection.add("hello");
        collection.add("hello");
        String[] objects = (String[]) collection.toArray();
        System.out.println(Arrays.toString(objects));
    }

执行结果如下:

java 泛型和String转换 泛型转化为string类型_java 泛型和String转换

对于这样的代码,我们在不了解泛型的理解是认为,在我们new出来collection之后,我们放的两个元素都是String类型的元素,因此我们就会想到取得时候利用强制类型转换,转换为String类型的数组去取,但是这段代码的底层原理远比我们想的要复杂的多,toArray()方法的返回值是一个Object【】数组,此处的强制类型实际上是将这个Object【】类型的数组强制类型转换为String【】数组,实际上,Object【】类型数组当中的每个元素并没有进行强制类型转换,因此,就会发生强制类型转换异常,只是运行时所抛出的异常,编译时期并不会察觉到。

 我们再看一段代码,再来进行思考:

class MyArrayList{
    private int[] elem;
    private int  usedSize;
    
    public MyArrayList(){
        this.elem = new int[10];
    }
    public void add(int val){
        this.elem[usedSize] = val;
        usedSize++;
    }
    public int get(int pos){
        return this.elem[pos];
    }
}

通过上面的代码我们思考:

(1)只能存放整数的类型,不通用

(2)能不能啥都可以放?String、Boolean....

我们对代码做出以下调整:

class MyArrayList{
    private Object[] elem;
    private int  usedSize;

    public MyArrayList(){
        this.elem = new Object[10];
    }
    public void add(Object val){
        this.elem[usedSize] = val;
        usedSize++;
    }
    public Object get(int pos){
        return this.elem[pos];
    }
}

这样就又回到了最开始的问题,存放元素时,不能指定元素,什么都可以放,并且当我们取出数据的时候,都需要进行强制类型转换。

那么:

1、能不能我指定这个顺序表的类型?

2、指定类型之后,是不是就只能放指定类型的数据呢?

3、取出数据能不能不进行强制类型转换?

解决方案——泛型

泛型的意义:

1、自动对类型进行检查

2、自动对类型进行强制类型转换

泛型的核心操作将类型作为参数进行传递。

我们先看代码如何实现:


class MyArrayList<E>{
    private E[] elem;
    private int  usedSize;

    public MyArrayList(){
        this.elem = (E[]) new Object[10];
    }
    public void add(E val){
        this.elem[usedSize] = val;
        usedSize++;
    }
    public Object get(int pos){
        return this.elem[pos];
    }
}

java 泛型和String转换 泛型转化为string类型_sed_02

 我们指定传递的类型为String类型,注意,此处传递的类型只能是包装类型,不能是基本数据类型,当我们放置整数类型时,就会自动帮我们检查到错误并提示我们不能放置整数类型,换句话说,泛型是编译时期的一种机制(擦除机制)。

什么又是擦除机制呢?

所谓擦除机制,就是在编译时,将所有的E类型替换为Object类型。(具体细节我们在深入理解泛型时描述)。

我们可以参考标准库当中的做法来理解泛型:


java 泛型和String转换 泛型转化为string类型_java_03

java 泛型和String转换 泛型转化为string类型_sed_04

 

 

java 泛型和String转换 泛型转化为string类型_java 泛型和String转换_05

获取时根据传递的参数对数据进行强制类型转换。