Java泛型

是什么

类型的参数化机制,将类型当成参数通过<>传给对应的类/接口/方法。

先看一个简单的例子

package testSwitch;

//<T>就是定义的泛型
class Generics <T>{
    T data;
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
}

public class TestGenerics {
    public static void main(String[] args) {
        //初始化时通过<Integer>的指定类型为Integer
        Generics<Integer> genericsObject = new Generics<Integer>();
        genericsObject.setData(10);
        Integer i = genericsObject.getData();
        System.out.println(i);

    }

}

 

他背后是什么原理呢?

类型擦除:在编译的时候是将所有的泛型类型T看成Object类型,然后根据T进行安全的强制转换。

这一点我们可以通过反编译清楚的看出来

class Generics
{
    Generics()
    {
    }

   //这里把所有的T都看成了Object类型
    public Object getData()
    {
        return data;
    }
    public void setData(Object data)
    {
        this.data = data;
    }
    Object data;
}

 
public class TestGenerics
{
    public TestGenerics()
    {
    }
    public static void main(String args[])
    {
        Generics genericsObject = new Generics();
        genericsObject.setData(Integer.valueOf(10));
        //这里增加的强制类型转换
        Integer i = (Integer)genericsObject.getData();
        System.out.println(i);
    }
}

 

 

使用泛型有什么好处?

  • 一套模板可以复用到很多类型中。
  • 强类型检查,保证了在编译器的类型安全。

 

下面还有几种使用场景的代码

  • 泛型方法
    //声明
    public <T> void showData(T t) {
        System.out.println(t + " and data " + data);;
    }

    //调用,直接赋值就可以了
    genericsObject.showData(20)
  • 泛型限定为某一类型及其子类: <T extends Number>
  • 泛型限定为某一类型及其父类: <T super Number>
class Generics {
    int data;
    //限定为Number的子类
    public <T extends Number> void showData(T t) {
        System.out.println(t + " and data " + data);;
    }
}


public class TestGenerics {
    public static void main(String[] args) {
        Generics genericsObject = new Generics();
        genericsObject.showData(12.2);
    }
}
  • 原始泛型类没有限定,但是我在使用的时候想加个限定,比如必须是某一类型及其子类:<? extends Number>
package testGenerics;
//定义原始无限定泛型
class Generics <T>{
    T data;
    public Generics(T data) {
        this.data = data;
    }

    public void showData() {
        System.out.println(data);
    }
}

class GenericsHelper{
    //在其他类中使用的时候限定泛型类型
    public static void showNewData(Generics<? extends Number> gen) {
        gen.showData();
    }
}

public class TestGenerics {
    public static void main(String[] args) {
        GenericsHelper.showNewData(new Generics<Integer>(10));
    }
}

 

  • 还有一种不常用,通配符<?>,一般用于获取类类型中。

   Class<?> classType = Class.forName(Java.lang.String); 

 

有什么缺点吗?

  • T不能是基本类型(因为Object无法持有基本类型)
  • 无法取得泛型的Class,只能获取到Pair
  • 无法判断带泛型的Class
  • 不能创建具体类型的泛型数组

 

posted @ 2018-06-23 22:28  darrenqiao  阅读(212)  评论(0编辑  收藏  举报