Java基础 - 泛型机制详解与实例解析

泛型是Java编程语言中的一项强大的特性,它提供了参数化类型的能力,使得代码更加灵活、安全,并提高了代码的重用性。

泛型其实就是为了参数化类型(在不创建新的类型的前提下,通过泛型指定的不同类型来控制形参具体限制的类型)。

1. 泛型的引入背景

在引入泛型之前,Java中的集合(如ArrayList、HashMap等)都是非泛型的,它们可以存储任意类型的对象,但在使用时需要进行强制类型转换,这带来了类型安全性和代码可读性的问题。泛型的引入就是为了解决这些问题,使得集合类能够在编译期检查元素的类型,并提供更加安全和通用的编程方式。

2. 泛型的基本概念

2.1 泛型类

泛型类是具有一个或多个类型参数的类。在类名后面使用尖括号<>定义类型参数,并在类的声明、方法的返回类型以及方法的参数中使用这些类型参数。

public class Box<T> {
    private T value;

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

    public T getValue() {
        return value;
    }
}

上面的例子中,Box类是一个泛型类,使用<T>定义了一个类型参数。这个类可以用来存储任意类型的值。

2.2 泛型方法

泛型方法是在调用时可以接受不同类型的参数的方法。泛型方法的类型参数在方法返回类型之前声明。

public <T> T identity(T element) {
    return element;
}

上述例子中,identity方法是一个泛型方法,接受一个类型为T的参数,并返回一个同样类型的值。

3. 泛型的实际应用

3.1 集合框架中的泛型

泛型广泛应用于Java的集合框架,使得我们能够在编译期间检测到类型错误。

List<String> stringList = new ArrayList<>();
stringList.add("Hello");
stringList.add("World");

// 编译时会报错,不允许添加非String类型的元素
// stringList.add(42);

for (String s : stringList) {
    System.out.println(s);
}

3.2 泛型通配符(重)

泛型通配符用来表示一种不确定的泛型类型,常用的通配符有?T extends SomeClassT super SomeClass

public static double sumOfList(List<? extends Number> list) {
    double sum = 0.0;
    for (Number num : list) {
        sum += num.doubleValue();
    }
    return sum;
}
// 接收Number的子类,如<? extends Integer> 则 需要接收Number
List<Integer> integers = Arrays.asList(1, 2, 3);
List<Double> doubles = Arrays.asList(1.5, 2.5, 3.5);

System.out.println(sumOfList(integers)); // 输出 6.0
System.out.println(sumOfList(doubles));  // 输出 7.5

泛型通配符上下限

<?> 无限制通配符 <? extends E> extends 关键字声明了类型的上限,表示此类型的子类或指定类 <? super E> super 关键字声明了类型的下界,表示此类型的父类或指定类

3.3 类型擦除

Java中的泛型是通过类型擦除来实现的,即在编译期间会将泛型信息擦除,转为原始类型。这导致在运行时无法获取泛型的实际类型参数。

public class GenericClass<T> {
    private T value;

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

    public T getValue() {
        return value;
    }
}

GenericClass<Integer> genericInt = new GenericClass<>();
GenericClass<String> genericString = new GenericClass<>();

System.out.println(genericInt.getClass() == genericString.getClass()); // 输出 true

4. 泛型的局限性和注意事项

4.1 无法创建泛型数组

由于类型擦除,Java不允许直接创建泛型数组。通常使用集合代替数组来存储泛型对象。

// 编译时会报错
// T[] array = new T[10];

List<T> list = new ArrayList<>();

4.2 泛型类型参数不能是基本数据类型

泛型的类型参数只能是类类型,不能是基本数据类型。如果需要使用基本数据类型,可以使用对应的包装类。

// 编译时会报错
// Box<int> intBox = new Box<int>();

Box<Integer> integerBox = new Box<>();

5. 总结

Java泛型机制通过提供参数化类型的能力,使得代码更加通用、安全。在实际应用中,泛型被广泛用于集合框架、泛型方法等方面,提供了更灵活、类型安全的编程方式。然而,泛型也存在一些局限性和注意事项,如类型擦除、无法创建泛型数组等。合理地使用泛型,将有助于提高代码的可读性、可维护性和重用性。

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

--土拨鼠--

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值