首页 > 其他分享 >泛型

泛型

时间:2024-08-07 19:49:50浏览次数:7  
标签:Java item List 类型 泛型 public

泛型

目录

泛型的定义

Java泛型是在Java SE 5中引入的一种特性,它允许你为你的类、接口和方法指定类型参数,从而使得代码更加类型安全和灵活。泛型的本质是参数化类型,即在编译时提供类型信息,以确保类型的正确性。

java复制public class Box<T> {
    private T t;

    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

泛型的作用

  • 类型安全:泛型提供了编译时类型检查,减少了运行时类型错误。
  • 消除类型转换:使用泛型可以减少类型转换,使代码更简洁。
  • 代码复用:泛型允许你编写更通用的类和方法,可以用于不同的数据类型。

泛型的特性

Java泛型是Java 5 引入的一个特性,它为Java语言带来了类型安全和代码复用性。以下是Java泛型的主要特性:

  • 类型安全
    泛型的主要目的是提供类型安全。使用泛型,你可以在编译时检查类型错误,避免在运行时出现类型转换异常。

  • 消除类型转换
    泛型消除了在集合中存储和检索对象时需要进行的类型转换。这使得代码更简洁,减少了出错的可能性。

  • 代码复用
    泛型允许你编写可以用于多种类型的通用类和方法,从而提高代码复用率。

  • 类型参数化
    泛型允许你为类、接口、方法定义类型参数,这些参数在实例化或调用时指定。

  • 类型推断
    Java编译器能够推断泛型的类型,这减少了代码的冗余,使得代码更加简洁。

  • 泛型通配符
    使用问号?可以定义一个通配符类型,它可以接受任何类型的参数。

  • 类型上限
    使用extends关键字,可以为泛型指定一个类型上限,即泛型参数必须是上限类型或其子类型。

  • 类型下限(不常用):
    使用super关键字,可以为泛型指定一个类型下限,但这种做法在Java中不常用。

  • 协变与逆变
    泛型是协变的,意味着如果ST的子类型,则List<S>List<T>的子类型。逆变通常用于方法参数,但Java泛型不支持泛型的逆变。

  • 类型擦除
    泛型的类型信息在编译时存在,但在运行时被擦除,这意味着运行时无法直接获取泛型的类型信息。

  • 泛型数组限制
    由于类型擦除,Java不允许创建泛型类型的数组。

  • 非重新实例化
    泛型类和接口不能被重新实例化,即不能使用泛型参数创建它们的子类。

  • 与现有代码的兼容性
    泛型被设计为与现有非泛型代码兼容,这允许逐步将泛型集成到现有代码库中。

  • 限制与原始类型
    当泛型类型使用未指定实际类型时,它被称为原始类型(如List而不是List<String>)。使用原始类型会失去泛型的类型安全。

  • 桥方法
    当泛型类继承非泛型类时,编译器会生成桥方法来保持二进制兼容性。

泛型的使用

定义泛型类

public class Box<T> {
    private T item;

    public void setItem(T item) {
        this.item = item;
    }

    public T getItem() {
        return item;
    }
}

使用泛型类

Box<String> stringBox = new Box<>();
stringBox.setItem("Hello, World!");
String item = stringBox.getItem();

泛型接口

public interface Stack<T> {
    void push(T item);
    T pop();
}

泛型方法

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

使用泛型方法

String[] strings = {"a", "b", "c"};
Utils.printArray(strings);
Integer[] numbers = {1, 2, 3};
Utils.printArray(numbers);

泛型通配符

public class WildcardTest {
    public static void printArrayWithBounds(List<? extends Number> list) {
        for (Number n : list) {
            System.out.println(n);
        }
    }

    public static void printArrayWithUnboundedWildcard(List<?> list) {
        for (Object obj : list) {
            System.out.println(obj);
        }
    }
}

泛型的类型限定

public class GenericClass<T extends Comparable<T>> {
    // T 必须实现了 Comparable 接口
    public void compare(T a, T b) {
        a.compareTo(b);
    }
}

泛型方法的类型限定

public class MathUtils {
    public static <T extends Number> double calculate(T a, T b, MathOperation<T> operation) {
        return operation.performOperation(a, b);
    }
}

interface MathOperation<T extends Number> {
    double performOperation(T a, T b);
}

泛型的类型擦除

Java泛型的类型信息在编译时被检查,但在运行时会被擦除,这意味着你不能直接获取泛型的类型信息:

Box<String> box = new Box<>();
System.out.println(box.getItem().getClass()); // 正确使用
System.out.println(box.getClass().getTypeParameters()); // 编译错误,因为类型信息已被擦除

泛型数组的限制

由于类型擦除,Java不允许创建泛型数组:

List<String>[] lists = new List<String>[10]; // 编译错误
List<String>[] lists = new ArrayList<String>[10]; // 正确

使用原始类型

有时,为了与旧代码兼容,你可能需要使用原始类型:

List list = new ArrayList(); // 使用原始类型
list.add("String"); // OK
list.add(1); // 编译时不报错,但运行时会抛出 ClassCastException

使用泛型时,应该尽量避免使用原始类型,以保持类型安全。

通过这些用法,你可以创建类型安全、灵活且可重用的代码。Java泛型是Java语言中一个非常重要的特性,广泛应用于集合框架、自定义数据结构和算法实现中。

标签:Java,item,List,类型,泛型,public
From: https://www.cnblogs.com/luoyiwen123/p/18347777

相关文章

  • JSON反序列化中的泛型问题及解决方法
    1、问题Java的泛型是编译期擦除,因此反序列化无法直接指定泛型类型:List<User>list=JsonbBuilder.create().fromJson(json,List<User>.class);编译不通过,改为List.class又达不到预期效果。2、解决办法jackson的做法:List<User>list=JsonbBuilder.create().fromJson(jso......
  • 泛型
    泛型1.什么是泛型在Java中,泛型(Generics)是Java5(也称为JavaSE5.0或JDK1.5)中引入的一个重要特性,它提供了一种编译时类型安全检测机制,允许程序员在类、接口和方法中使用类型参数(TypeParameters)。这些类型参数在编译时会被具体的类型所替换,从而实现了代码的复用和类型安全。泛......
  • 泛型
    泛型什么是泛型?泛型(Generictype或者generics)是对Java语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。可以在集合框架(Collectionframework......
  • Java泛型中的PECS 原则
    在Java泛型中,使用extends和super关键字来定义通配符的上界和下界,主要是为了保证类型安全,并且能够灵活地处理不同类型的集合。具体来说,使用extends和super的原因可以通过理解PECS(ProducerExtends,ConsumerSuper)原则来解释。PECS原则ProducerExtends:如果......
  • 集合泛型,集合遍历,集合工具类
    集合泛型,集合遍历,集合工具类一.集合泛型在Java中,集合泛型(CollectionGenerics)是Java泛型(Generics)在集合框架(CollectionsFramework)中的一个重要应用。泛型提供了一种编译时类型安全检测机制,允许程序员在编译时期而不是运行时检查非法的类型。当将泛型应用于集合时,可以指定集合......
  • 集合泛型
    Java集合框架中的泛型是Java5引入的一个特性,它允许开发者在编译时就确定集合中元素的类型,从而避免类型转换和潜在的类型安全问题。以下是一些常用的Java集合类和它们使用泛型的例子:ArrayList-动态数组,提供快速随机访问。ArrayList<String>list=newArrayList<>();......
  • 集合泛型
    集合泛型在Java中,泛型(Generics)是一种强大的特性,它允许程序员在编译时进行类型安全检查。当泛型应用于集合时,可以确保集合中只能存储指定类型的元素,从而避免了类型转换的错误和运行时异常。泛型的基本使用泛型在使用时通常遵循以下格式:GenericClass<Type>object=newGeneri......
  • java9-泛型
    1.泛型的简介1.1什么是泛型        泛型是一种特殊的数据类型。它是Java的一个高级特性。在Mybatis、Hibernate这种持久化框架,泛型更是无处不在。在这之前,不管我们在定义成员变量时,还是方法的形参时,都要规定他们的具体类型。所以提出猜想,有没有一种可能,一次声......
  • 【Java基础知识3】泛型
    一、泛型的意义泛型的本质是将类型参数化,从而达到代码复用。即:在不创建新的类型下,通过泛型指定不同类型来控制形参具体类型,简单来讲就是,当我们不知道用什么数据类型接收数据的情况下,可以使用泛型来接收。代码示例:未使用泛型情况下:privatestaticintadd(inta,intb){......
  • c#:泛型
    泛型允许你定义一个类、接口或方法时不指定具体的数据类型,而是使用一个或多个类型参数类型安全:编译器在编译时检查类型,减少运行时错误。代码重用:相同的代码可以处理不同的数据类型,避免重复代码。性能:避免了装箱和拆箱的性能损失,尤其是在处理值类型时。点击查看代码usingS......