Java-基础-泛型

目录

  • 1 基本概念
  • 2 泛型的运用
    • 2.1 泛型类
    • 2.2 泛型接口
    • 2.3 泛型方法
    • 2.4 泛型数组
  • 3 泛型通配符
  • 4 泛型上下边界
  • 5 参考文献

1 基本概念

  • 泛型,也称“参数化类型”。
  • 通常定义方法的时候要有形参,调用方法的时候传入实参。
  • 那么参数化类型怎么理解?顾名思义,就是将原来的形参参数化,调用方法的时候再传入具体类型的实参进行使用,达到同一个类/接口可以创建不同类型的实例对象。若放在创建数组时,则用于定义数组中的数据类型。
  • 泛型的特征:注意,泛型只在编译阶段有效,在编译阶段协助开发人员提早发现错误(如发现ClassCaseException),而编译阶段过后会去范型化,再进入运行阶段运行。
  • 泛型的目的:泛型主要用于简化开发,保证良好的代码质量。

2 泛型的运用

2.1 泛型类

  • 泛型类可以实现同一个类创建不同实参类型的对象。
  • 泛型类用格式定义,T即形参,T可以更改为任意标识,常见的如T、E、K、V等
    代码例子如下:
/**
 * 通用的泛型类
 * @param    //泛型,对类的形参进行了参数化,即在实例化此对象时,再指定T的具体类型
 */
class Generic<T>{   //此处的代表此类是泛型类,T可以更改为任意标识,常见的如T、E、K、V等
    private T key;  //key这个成员变量的类型为T,T的类型由外部指定
    public Generic(T key){  //泛型构造方法形参key的类型也为T,T的类型由外部指定
        this.key = key;
}
//注意,这不是一个泛型方法,这只是泛型类中的一个普通成员方法
    public T getKey(){     //getKey的返回值类型为T,T的类型由外部指定
        return key;
    }
}
//给泛型类的T定义为形参String,同时传入的实参也是String类型
Generic<String> genericString = new Generic<String>("string");
//给泛型类的T定义为形参Integer,同时传入的实参也是Integer类型
Generic<Integer> genericInteger = new Generic<Integer>(123);

2.2 泛型接口

  • 泛型接口与泛型类基本一致。
    代码例子如下:
/**
 * 通用的泛型接口
 * @param    //泛型,对类的形参进行了参数化,即在实例化此对象时,再指定T的具体类型
 */
interface Generic<T>{
    public T next();
}
/**
 * 实现通用的泛型接口
 */
class FruitGenerator implements Generic<String>{    //指定泛型的具体类型为String

    private String[] fruits = new String[]{"Apple", "Banana", "Pear"};

    @Override
    public String next() {  //重写next方法
        Random rand = new Random();
        return fruits[rand.nextInt(3)];
    }
}

2.3 泛型方法

//public后的定义此方法为泛型方法,这里的中的泛型数量可以多个,如
public <T> T showKeyName(Generic<T> container){
    System.out.println("container key:" + container.getKey());
    T test = container.getKey();
    return test;
}
/**
 * 通用的泛型类
 * @param    //泛型,对类的形参进行了参数化,即在实例化此对象时,再指定T的具体类型
 */
class Generic<T>{   //此处的代表此类是泛型类,T可以更改为任意标识,常见的如T、E、K、V等
    private T key;  //key这个成员变量的类型为T,T的类型由外部指定

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

    //注意,这不是一个泛型方法,这只是泛型类中的一个普通成员方法
    public T getKey(){     //getKey的返回值类型为T,T的类型由外部指定
        return key;
    }

    //注意,这是一个泛型方法,但是这里的T和此泛型类中的T不是同一个,这里的T是重新声明的新T,参数中的T也是新T
    public <T> void testMethod(T t){
        System.out.println(t.toString());
    }
}

2.4 泛型数组

//即泛型,定义这个数组中的值类型只能是String
List<String> stringList = new ArrayList<String>(); 
//即泛型,定义这个数组中的值类型只能是Integer   
List<Integer> integerList = new ArrayList<Integer>();    

3 泛型通配符

  • 当不知道具体实现类型的时候,可以使用通配符(?)代替,通配符(?)是类型实参,是所有类的父类,只能使用Object类中的功能
    代码例子如下:
/**
 * 通用的泛型类
 * @param    //泛型,对类的形参进行了参数化,即在实例化此对象时,再指定T的具体类型
 */
class Generic<T>{   //此处的代表此类是泛型类,T可以更改为任意标识,常见的如T、E、K、V等
    private T key;  //key这个成员变量的类型为T,T的类型由外部指定

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

    //注意,这不是一个泛型方法,这只是泛型类中的一个普通成员方法
    public T getKey(){     //getKey的返回值类型为T,T的类型由外部指定
        return key;
    }

    //注意,这是一个泛型方法,但是这里的T和此泛型类中的T不是同一个,这里的T是重新声明的新T,参数中的T也是新T
    public <T> void testMethod(T t){
        System.out.println(t.toString());
    }
}
//当不知道具体实现类型的时候,可以使用通配符(?)代替,通配符(?)是类型实参,是所有类的父类,只能使用Object类中的功能
public static void showKeyValue(Generic<?> obj){
    System.out.println(obj.getKey());
}
//给泛型类的T定义为形参String,同时传入的实参也是String类型
Generic<String> genericString = new Generic<String>("string");
//给泛型类的T定义为形参Integer,同时传入的实参也是Integer类型
Generic<Integer> genericInteger = new Generic<Integer>(123);
showKeyValue(genericString);    //因为showKeyValue方法中使用了通配符(?),所以Generic中的泛型可以用任何类型
showKeyValue(genericInteger);   //因为showKeyValue方法中使用了通配符(?),所以Generic中的泛型可以用任何类型

4 泛型上下边界

  • 代表此类是泛型类,T的具体实现类型必须是继承于Number的,即定义了泛型的上下界限。
    代码例子如下:
//此处的代表此类是泛型类,T的具体实现类型必须是继承于Number的,即定义了泛型的上下界限
class Generic2<T extends Number>{
    private T key;

    public Generic2(T key){
        this.key = key;
    }

    public T getKey(){
        return key;
    }
}

5 参考文献

java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一

你可能感兴趣的:(java,开发语言,后端)