泛型Generic

2022-10-25 15:36:51 浏览数 (1)

泛型Generic

  • 概念
  • 特点
  • 泛型通配符
  • 使用
    • 泛型类
    • 泛型接口
    • 泛型方法

概念

泛型,即“参数化类型”。类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

特点

泛型只在编译阶段有效,但是在编译之后程序会采取去泛型化的措施。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。

代码语言:javascript复制
List<String> stringArrayList = new ArrayList<String>();
List<Integer> integerArrayList = new ArrayList<Integer>();

Class classStringArrayList = stringArrayList.getClass();
Class classIntegerArrayList = integerArrayList.getClass();

if(classStringArrayList.equals(classIntegerArrayList)){
    System.out.println("泛型测试:二者类型相同");
}
//结果输出:泛型测试:二者类型相同

总的来说,泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型,但是不同版本的泛型类实例是不兼容的。如Generic< Integer>不能被看作为Generic< Number>的子类,虽然Integer是Number的子类。

泛型通配符

正如上面所说Generic< Integer>不能被看作为Generic< Number>的子类,针对这个问题,通配符可以解决。 此处是类型实参,而不是类型形参 ,与Integer、Number一样都是一种实际的类型,用来表示未知类型。另一种理解方式,它可以看作是所有类型的父类。

代码语言:javascript复制
public static void print (Generic<?> obj){
        System.out.println("success");
}

Generic<Integer> generic1 = new Generic(123);
Generic<String>  generic2 = new Generic("abc");
Class.print(generic1);
Class.print(generic2);

使用

泛型类

代码语言:javascript复制
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T>{ 
    //key这个成员变量的类型为T,T的类型由外部指定  
    private T key;

    public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定
        this.key = key;
    }

    public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定
        return key;
    }
}

//使用1:泛型的类型参数只能是类类型(包括自定义类),不能是简单类型
Generic<Integer> genericInteger = new Generic<Integer>(123);
//使用2:如果不传入泛型类型实参的话,在泛型类中使用泛型的方法或成员变量定义的类型可以为任何的类型。
Generic genericInteger = new Generic("abc");

注意:不能对确切的泛型类型使用instanceof操作。

泛型接口

与泛型类相似,常用于各种类的生产器中。

代码语言:javascript复制
//定义一个泛型接口
public interface Generator<T> {
    public T next();
}

//实现泛型接口,为传入参数:声明类时必须加入泛型,否则报错“Unknow Class”
class Print<T> implements Generator<T>{
    @Override
    public T next() {
        return null;
    }
}

//实现泛型接口,传入参数
public class Print implements Generator<String> {
    @Override
    public String next() {
        return "Can you see me?";
    }
}

泛型方法

泛型方法,是在调用方法的时候指明泛型的具体类型 。

代码语言:javascript复制
/**
 * 泛型方法的基本介绍
 * @param tClass 传入的泛型实参
 * @return T 返回值为T类型
 * 说明:
 *     1)public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。
 *     2)只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
 *     3)<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
 *     4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
 */
public <T> T genericMethod(Class<T> tClass)throws InstantiationException ,
  IllegalAccessException{
        T instance = tClass.newInstance();
        return instance;
}

泛型类中可以有泛型方法 可以有多个泛型、加…等待

参考博客:https://www.cnblogs.com/coprince/p/8603492.html

0 人点赞