0
点赞
收藏
分享

微信扫一扫

Java基础【泛型】

兵部尚输 03-27 07:00 阅读 4

什么是泛型

使用泛型的好处

代码重用:使用泛型可以编写出与特定数据类型无关的通用算法和数据结构,从而提高代码的重用性。

类型安全:通过在编译时进行类型检查,可以避免在运行时出现类型转换错误,提高程序的健壮性和安全性。

减少重复代码:在没有泛型的情况下,可能需要为每种数据类型都编写相似的代码,而使用泛型可以减少重复的代码量。

泛型如何使用

  1. 使用泛型的集合接口和类
// 使用泛型的 List 接口和 ArrayList 类
import java.util.List;
import java.util.ArrayList;

public class GenericListExample {
    public static void main(String[] args) {
        List<String> stringList = new ArrayList<>();
        stringList.add("Hello");
        stringList.add("World");
        
        List<Integer> intList = new ArrayList<>();
        intList.add(123);
        intList.add(456);
        
        System.out.println("String list: " + stringList);
        System.out.println("Integer list: " + intList);
    }
}

  1. 使用泛型的集合方法
// 使用泛型的 Collection 接口方法
import java.util.ArrayList;
import java.util.Collection;

public class GenericCollectionMethods {
    public static void main(String[] args) {
        Collection<String> stringCollection = new ArrayList<>();
        stringCollection.add("Apple");
        stringCollection.add("Banana");
        
        Collection<Integer> intCollection = new ArrayList<>();
        intCollection.add(10);
        intCollection.add(20);
        
        // 使用泛型的 size() 方法获取集合大小
        System.out.println("String collection size: " + stringCollection.size());
        System.out.println("Integer collection size: " + intCollection.size());
        
        // 使用泛型的 contains() 方法检查元素是否存在
        System.out.println("Contains 'Banana': " + stringCollection.contains("Banana"));
        System.out.println("Contains 30: " + intCollection.contains(30));
    }
}

  1. 使用泛型的 Map 接口和 HashMap 类
// 使用泛型的 Map 接口和 HashMap 类
import java.util.Map;
import java.util.HashMap;

public class GenericMapExample {
    public static void main(String[] args) {
        Map<String, Double> priceMap = new HashMap<>();
        priceMap.put("Apple", 2.5);
        priceMap.put("Banana", 1.0);
        
        System.out.println("Price of Apple: " + priceMap.get("Apple"));
        System.out.println("Price of Banana: " + priceMap.get("Banana"));
    }
}

泛型的继承

// 泛型的继承示例
class Box<T> {
    private T t;
    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

// 继承泛型类的子类
class BoxSubclass<T> extends Box<T> {
    // 子类可以保留父类的泛型类型
}

// 继承非泛型类的子类
class NonGenericBoxSubclass extends Box<String> {
    // 子类可以指定具体的泛型类型
}

通配符

使用 ? extends T:
表示通配符所代表的类型是 T 的子类型(包括 T 本身),在使用时可以安全地获取类型为 T 的对象或其子类型的对象。

// 使用 ? extends T 的通配符
public void processElements(List<? extends Number> elements) {
    for (Number n : elements) {
        // 在这里可以安全地获取 Number 或其子类的对象
    }
}

使用 ? super T:
表示通配符所代表的类型是 T 的父类型(包括 T 本身),在使用时可以安全地向集合中添加类型为 T 的对象或其父类型的对象。

// 使用 ? super T 的通配符
public void addElement(List<? super Integer> list) {
    list.add(10);  // 可以安全地向集合中添加 Integer 或其父类的对象
}

泛型使用注意事项

类型擦除:Java 中的泛型是通过类型擦除(Type Erasure)实现的,编译器在编译时会将泛型类型擦除为原始类型。这意味着在运行时无法获取泛型的具体类型信息。因此,在泛型代码中无法使用基本类型作为类型参数,只能使用对象类型。

通配符限定:通配符(Wildcard)可以用来表示未知类型,通配符可以用于方法参数、泛型类的类型参数等。通配符有上界通配符(? extends T)和下界通配符(? super T),在使用通配符时需要注意通配符的限定条件。

类型转换和 instanceof 操作符:由于类型擦除的存在,无法直接创建泛型类型的实例。在某些情况下,可能需要进行类型转换,但要谨慎处理类型转换操作,以避免出现 ClassCastException 异常。同时,由于类型擦除的原因,不能使用 instanceof 操作符检查泛型类型。

泛型数组:在 Java 中不能直接创建泛型数组,如 List[] array = new List[10]; 是非法的。可以使用泛型集合代替泛型数组的使用。

泛型方法:除了泛型类,Java 还支持泛型方法。在编写泛型方法时,需要注意泛型方法的定义和使用方式,以确保正确传递类型参数。

擦除后的限制:由于类型擦除的存在,可能会导致一些限制,如不能直接创建泛型类型的实例、不能使用基本类型作为类型参数等。在编写泛型代码时,需要考虑到这些限制。

举报

相关推荐

0 条评论