首先提到的是,这篇博客参考自《Effective java》和一篇鼎鼎有名的博客:

首先是我对于泛型这个概念的理解:

顾名思义,也就是广泛的类型,也就是不是具体指向某一个类型,就相当于“参数化类型”,一般就是先有类或者接口的名称,在加一个尖括号(<>)来具体指向实际的类型,比如List,也就是特指list中的Strng.使得存放的时候更精确,在运行之前就能发现存在错误与否。

这也就引出了一个很有意思的点,泛型的适用类型
先写一段代码:

import java.util.ArrayList;
import java.util.List;

public  class test2020926{

    public static void main(String[] args) {
       List<String> stringArrayList=new ArrayList<String>();
       List<Integer> integerArrayList=new ArrayList<Integer>();
       Class classStringArrayList=stringArrayList.getClass();
       Class classStringArraylist=integerArrayList.getClass();
       
       if(classStringArrayList.equals(classStringArraylist)){
           //判断两个是不是同一个类型
           System.out.println("两个类型是一样的");
       }
    }
}

这段代码最后的输出就是“两个类型是一样的”,所以***证明在编译之后程序会采取去泛型化的措施,也就是Java的泛型只在编译阶段有效,编译结束,不出现错误之后,就会把对应的相关信息擦去,不会进入到运行阶段***。

接着就是对于泛型的使用情况

  1. 泛型类
  2. 泛型接口
  3. 泛型方法

首先第一个就是泛型类:他一般就是

class 类名称<泛型的标识>{
}

举个“更生动”的例子

public class Generic<T>{
//这里T是需要指定类型的
private T key;
public Genaric(T key){
this.key=key;
}
//再还有方法
public T getkey(){
return key;
}
}

值得注意的是,这里的T,可以是指定类型,并且指定了就需要传入指定的参数,比如:

Generic<String> ge=new Generic<String>("key");

传入的是String,参数里也是String类型

可以不指定参数类型,根据传入的泛型实参做相应的限制。比如:

Generic generic=new Generic(222);

再者就是泛型接口
他的定义和泛型类其实差不太多,毕竟接口就可以当做是特殊类。
而接口除了定义以外,还有另一个重要的功能就是被实现,于是就出现两种情况。
1.当实现泛型接口的类 ,未传入泛型的实参,比如

class A<T> implements G<T>{
}

需要在A这边也声明,不然会报错
2.当实现泛型接口的类,传入泛型实参
class B implements G{
}
这里B就不需要声明了,并且要把G里面的方法也同样替代成传入的String类型

再介绍方法之前,介绍一下***泛型通配符***
其实就是

List<?>

这种类型。并且这个?,可以看作是一个类型实参,就是那种和Sring Integer一样的类型,直接当成所有类的父类都行。

最后是泛型方法
最重要的一句话

只有声明了的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法

public <T> T showKeyName(Generic<T> container){
        System.out.println("container key :" + container.getKey());
        //当然这个例子举的不太合适,只是为了说明泛型方法的特性。
        T test = container.getKey();
        return test;
    }

这个模式才是最正确的

java 泛型单例模式 java泛型理解_泛型方法


PS,还有个静态方法与泛型:

如果静态方法要使用泛型的话,必须将静态方法也定义成泛型方法,用代码表示就是:

public class StaticGenerator<T> {
    ....
    ....
    /**
     * 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法)
     * 即使静态方法要使用泛型类中已经声明过的泛型也不可以。
     * 如:public static void show(T t){..},此时编译器会提示错误信息:
          "StaticGenerator cannot be refrenced from static context"
     */
    public static <T> void show(T t){

    }
}

总之就是需要在方法上 也加一个 T

最后一句话,泛型在我看来,最大的作用还是在于提高代码的规范性。