Java 泛型

本文详细介绍了Java泛型的概念,如参数化类型,以及在集合类中的经典应用。泛型主要特性在于编译时有效,提供类型安全。文中通过示例详细阐述了泛型类、泛型接口、泛型方法(包括基本写法、静态方法、可变参数方法)的使用方式,帮助读者深入理解Java泛型的运用。
摘要由CSDN通过智能技术生成

目录

1. 什么是 Java 泛型(generics)?

2. 经典使用场景

3. 特性

4. 泛型的使用

4.1 泛型类

4.2 泛型接口

4.3 泛型方法

4.3.1 基本写法

4.3.2 泛型类中的泛型方法

4.3.3 泛型类中的静态泛型方法

4.3.4 可变参数泛型方法


1. 什么是 Java 泛型(generics)?

泛型,即参数化类型。

变量可以是参数,实际使用时,再确定它的值。那么,类型,也可以是一个参数,实际使用时,再确定它到底是什么类型。

 

2. 经典使用场景

Java 的集合类中对泛型的使用极为广泛,如 List,Set,Map等。

 

举个例子:

class Scratch {
    public static void main(String[] args) {
        // 未指定 List 内的类型
        List arrayList = new ArrayList();
        arrayList.add("aaaa");
        arrayList.add(11);

        for(int i=0; i<arrayList.size();i++){
            String item = (String)arrayList.get(i);
            System.out.println(item);
        }
        System.out.println("end");
    }
}

此时的输出结果是:

第一个 String 元素“aaaa”被正确输出,第二个 int 元素被强制转换为 String 类型时,会报异常。

但是如果将强制转换去掉,直接输出,就不会报错。

for(int i=0; i<arrayList.size();i++){
 // String item = (String)arrayList.get(i);
    System.out.println(arrayList.get(i));
}

在没有指定类型时,ArrayList变量可以存放任意类型的值,且不会报错。

 但是如果在定义ArrayList变量时,指定类型,就只能 add 指定类型的变量。(编译期间就会检查 add 的是否是指定类型的值)

 

3. 特性

泛型只在编译阶段有效。

在编译之后程序会采取去泛型化的措施。

 

4. 泛型的使用

泛型的使用包括:泛型类,泛型接口,泛型方法。

4.1 泛型类

基本写法:

//此处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;
    }
}

 

4.2 泛型接口

泛型接口与泛型类的定义及使用基本相同。

泛型接口常被用在各种类的生产器中。

基本写法:

//定义一个泛型接口
public interface Generator<T> {
    public T next();
}

实现泛型接口的类,可以传入泛型实参,也可以不传入泛型实参:

// 不传入泛型实参
class FruitGenerator<T> implements Generator<T>{
    @Override
    public T next() {
        return null;
    }
}

// 传入泛型实参
public class FruitGenerator implements Generator<String> {

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

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

 

4.3 泛型方法

4.3.1 基本写法

public <T> T genericMethod(Class<T> tClass)throws InstantiationException ,
  IllegalAccessException{
        T instance = tClass.newInstance();
        return instance;
}

4.3.2 泛型类中的泛型方法

public class GenericFruit {
    class Fruit{
        @Override
        public String toString() {
            return "fruit";
        }
    }

    class Apple extends Fruit{
        @Override
        public String toString() {
            return "apple";
        }
    }

    class Person{
        @Override
        public String toString() {
            return "Person";
        }
    }

    class GenerateTest<T>{
        public void show_1(T t){
            System.out.println(t.toString());
        }


        //在泛型类中声明了一个泛型方法,使用泛型T,注意这个T是一种全新的类型,可以与泛型类中声明的T不是同一种类型,比如写作E。
        public <T> void show_2(T t){
            System.out.println(t.toString());
        }
    }

    public static void main(String[] args) {
        Apple apple = new Apple();
        Person person = new Person();

        GenerateTest<Fruit> generateTest = new GenerateTest<Fruit>();
        //apple是Fruit的子类,所以这里可以
        generateTest.show_1(apple);
        //编译器会报错,因为泛型类型实参指定的是Fruit,而传入的实参类是Person
        //generateTest.show_1(person);

        //使用这两个方法都可以成功
        generateTest.show_2(apple);
        generateTest.show_2(person);

    }
}

4.3.3 泛型类中的静态泛型方法

在泛型类中使用泛型的静态方法时,需要将此静态方法写成泛型方法的形式,否则编译报错。

public class StaticGenerator<T> {
    
    public static <T> void show(T t){
        *****
    }
}
 

4.3.4 可变参数泛型方法

当泛型方法使用可变参数时:

public <T> void printMsg( T... args){
    for(T t : args){
        System.out.println(t);
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值