java中的泛型

引言

当我们编写代码时,可能会遇到需要处理不同类型的数据的情况。在传统的编程中,你需要为每种类型编写不同的代码来处理数据,这样会导致代码的重复和冗余。为了解决这个问题,Java 1.5引入了泛型(Generics)的概念。

什么是泛型?泛型是一种编程范式,允许在创建类、接口和方法时使用类型参数。这些类型参数在实际使用时被指定为具体的数据类型,从而实现通用性。通过使用泛型,你可以编写通用的代码,能够处理多种类型的数据,而无需重复编写相似的代码。

泛型的优点有以下几个方面:

  1. 类型安全:泛型能够在编译期间对类型进行检查,可以避免一些类型转换错误和运行时异常。
  2. 重用代码:通过泛型,可以编写通用的代码,适用于多种类型的数据,提高代码的重用性。
  3. 简化代码:使用泛型可以减少冗余代码的编写,使代码更加简洁和易读。

泛型的定义格式如下:

  • <类型>: 指定一种类型的格式.尖括号里面可以任意书写,一般只写一个字母.例如: <E> <T>。

  • <类型1,类型2…>: 指定多种类型的格式,多种类型之间用逗号隔开.例如: <E,T> <K,V>

在java中,泛型主要通过泛型类、泛型方法、泛型接口和通配符等几种方式使用,接下来,本文将详细介绍这几种方式。

泛型类

泛型类是一种具有参数化类型的类,在定义时使用了一个或多个类型参数,多个类型参数之间需要用逗号隔开。这些类型参数可以在实例化泛型类时指定为具体的数据类型,使得该类可以适用于各种不同的数据类型,从而提高了代码的通用性和灵活性。

泛型类的定义格式:修饰符 class 类名<类型> {  }。

下面来举一个具体的例子:

1.声明泛型类

public class Box<T> {
    private T value;

    public void setValue(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }
}

在上面的例子中,Box 是一个泛型类,<T> 表示这是一个类型参数,它允许在类内部使用这个未知的类型 T

2.实例化泛型类

Box<Integer> integerBox = new Box<>();
integerBox.setValue(10);
System.out.println("Value: " + integerBox.getValue()); // 输出: Value: 10

Box<String> stringBox = new Box<>();
stringBox.setValue("Hello");
System.out.println("Value: " + stringBox.getValue()); // 输出: Value: Hello

在实例化泛型类时,通过 <> 括号内指定具体的数据类型,例如 Box<Integer> 表示使用Integer类型实例化泛型类 Box

注意:

类型擦除:Java 中的泛型在编译时会进行类型擦除,泛型信息在运行时被擦除。例如,无法在运行时获取泛型的实际类型参数。

静态上下文中的类型参数:静态方法或静态变量无法直接引用泛型类中定义的类型参数,因为在静态上下文中类型参数尚未确定。

泛型类不能使用基本数据类型作为类型参数,只能使用引用类型。但可以使用对应的包装类(如Integer替代int)。

泛型方法

泛型方法是一个具有类型参数的方法,它可以在方法的定义中使用类型参数,以表示可以处理多种类型的数据。通过使用泛型方法,我们可以编写通用的代码,能够适用于多种类型的数据,而无需为每种类型编写不同的方法。

泛型方法的定义格式:修饰符 <类型> 返回值类型 方法名(类型 变量名) {  }

下面是一个使用泛型方法的例子:

public class Generic {
    public <T> void printArray(T[] array) {
        for (T item : array) {
            System.out.println(item);
        }
    }
}

在上面的示例中,我们定义了一个printArray 泛型方法,它接受一个类型为T[]的数组作为参数,并遍历输出数组元素。在方法的定义中使用了类型参数T,以表示该方法可以处理多种类型的数组。

使用泛型方法时,需要在方法调用时指定类型参数的具体类型。例如:

Generic myMethod = new Generic();

Integer[] intArray = {1, 2, 3, 4, 5};
myMethod.printArray(intArray);

String[] stringArray = {"Hello", "World"};
myMethod.printArray(stringArray);

在上面的示例中,我们创建了一个Generic对象,并分别使用 printArray 泛型方法输出了一个整型数组和一个字符串数组的元素。

通过使用泛型方法,我们能够编写通用的代码,提高代码的重用性和灵活性。泛型方法是 Java 中非常有用的特性,在实际开发中经常会遇到,能够简化代码并提高代码的可读性和维护性。

泛型接口

泛型接口是一个具有类型参数的接口,它可以在接口的定义中使用类型参数,以表示可以操作多种类型的数据。通过使用泛型接口,我们可以编写通用的代码,能够适用于多种类型的数据,而无需为每种类型编写不同的接口。

泛型接口的定义格式:修饰符 interface 接口名<类型> {  }

下面是一个使用泛型接口的例子:

public interface Generic<T> {
    void show(T t);
}

在上面的示例中,我们定义了一个 Generic 泛型接口,它有一个类型参数 T。该接口有一个show抽象方法。

泛型接口的实现类有两种:

实现类1:定义实现类时,定义和接口相同泛型,创建实现类对象时明确泛型的具体类型

例:

public class GenericImpl1<T> implements Generic<T> {
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}

实现类2:定义实现类时,直接明确泛型的具体类型

例:

public class GenericImpl2 implements Generic<Integer>{
     @Override
     public void show(Integer t) {
          System.out.println(t);
     }
}

 类型通配符

类型通配符是一种在泛型代码中使用的特殊符号,用于表示未知的类型。它可以用于方法参数、方法返回值以及泛型类中的字段等位置,以增加代码的灵活性和重用性。

在 Java 中,类型通配符使用问号 ? 表示。它可以被用于以下三种形式:

  • 类型通配符: <?>

    • ArrayList<?>: 表示元素类型未知的ArrayList,它的元素可以匹配任何的类型

    • 但是并不能把元素添加到ArrayList中了,获取出来的也是父类类型

  • 类型通配符上限: <? extends 类型>

    • ArrayListList <? extends Number>: 它表示的类型是Number或者其子类型

  • 类型通配符下限: <? super 类型>

    • ArrayListList <? super Number>: 它表示的类型是Number或者其父类型

使用类型通配符的主要目的是在泛型代码中提供更大的灵活性。它允许我们编写适用于多种类型的代码,而不需要具体指定类型参数。

以下是一些使用类型通配符的示例:

public void processList(List<?> list) {
    // 对列表进行处理
}

public void addNumbers(List<? extends Number> list) {
    // 向列表中添加数字
}

public void printElements(List<? super Integer> list) {
    // 打印列表元素
}

在上面的示例中,processList 方法接受一个未知类型的列表作为参数,在方法内部可以对列表进行处理。addNumbers 方法接受一个元素类型为 Number 或其子类的列表,并向列表中添加数字。printElements 方法接受一个元素类型为 Integer 或其父类的列表,并打印列表元素。

通过使用类型通配符,我们可以编写更加通用和灵活的泛型代码,提高代码的重用性和可读性。它是 Java 泛型特性中非常有用的一部分,能够帮助我们处理多种类型的数据。

好了,今天的内容就到处为止,学习java是一个漫长的过程,大家加油!路漫漫其修远兮,吾将上下而求索。

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值