什么是泛型?

您所在的位置:网站首页 编程语言泛型 什么是泛型?

什么是泛型?

2024-07-09 16:03| 来源: 网络整理| 查看: 265

什么是泛型?

泛型(Generics)是一种在编程中提供类型安全和代码复用的机制。

泛型允许在定义类、接口、方法时不指定具体的类型,而是在使用时再明确。这样做的好处有很多:

提高了代码的复用性:通过使用泛型,可以编写一个通用的逻辑,适用于多种不同的类型,而无需为每种类型都单独编写类似的代码。增强了类型安全性:可以避免在运行时出现类型转换错误。例如,如果一个方法期望接收整数类型,使用泛型可以确保不会错误地传入其他类型的数据。

比如说,在 Java 中,我们可以定义一个泛型类 Box 来表示一个可以存储任意类型对象的盒子:

class Box { private T item; public void setItem(T item) { this.item = item; } public T getItem() { return item; } }

在这个例子中,Box类是一个泛型类,其中T是类型参数。T可以在Box类的定义中用作变量类型。可以创建 Box 的不同类型实例,如 Box 用于存储整数,Box 用于存储字符串。

为什么需要泛型?

在没有泛型的情况下,我们可能需要为每个数据类型都编写相应的类或方法,这样会导致代码冗余,并且难以维护。而有了泛型,我们可以将类型作为参数传递给类或方法,使其具有通用性,可以处理多种类型的数据。

适用于多种数据类型执行相同的代码

private static int add(int a, int b) { System.out.println(a + "+" + b + "=" + (a + b)); return a + b; } private static float add(float a, float b) { System.out.println(a + "+" + b + "=" + (a + b)); return a + b; } private static double add(double a, double b) { System.out.println(a + "+" + b + "=" + (a + b)); return a + b; }

如果没有泛型,要实现不同类型的加法,每种类型都需要重载一个add方法;通过泛型,我们可以复用为一个方法:

private static double add(T a, T b) { System.out.println(a + "+" + b + "=" + (a.doubleValue() + b.doubleValue())); return a.doubleValue() + b.doubleValue(); }  基本语法

泛型的基本语法包括泛型类、泛型接口和泛型方法。

泛型类

public class Box { private T content; public void setContent(T content) { this.content = content; } public T getContent() { return content; } }

泛型接口

public interface Container { void add(T item); T get(int index); }

泛型方法

public class Util { public static void printArray(T[] array) { for (T element : array) { System.out.print(element + " "); } System.out.println(); } }

使用示例

泛型类使用

Box stringBox = new Box(); stringBox.setContent("Hello"); String content = stringBox.getContent(); System.out.println(content);

泛型方法使用

Integer[] intArray = {1, 2, 3, 4, 5}; Util.printArray(intArray); String[] strArray = {"A", "B", "C"}; Util.printArray(strArray);

好啦,到这就可以啦,下面的是扩展,可以了解

泛型的实现原理

Java 的泛型实现采用了类型擦除的方式。这意味着在编译阶段,泛型类型的信息会被擦除,替换为其上限类型(如果没有指定上限类型,则默认是 Object 类型)。

例如,对于 List 这样的泛型类型,在编译后的字节码中,它会被视为 List 。在运行时,实际上并不存在具体的泛型类型信息。

这样做的好处是保持了 Java 字节码的向后兼容性,但也带来了一些限制,比如不能在运行时获取泛型的具体类型参数。

如何编写一个泛型类?

首先,按照某种类型,例如:String,来编写类:

public class Pair { private String first; private String last; public Pair(String first, String last) { this.first = first; this.last = last; } public String getFirst() { return first; } public String getLast() { return last; } }

然后,把特定类型String替换为T,并申明:

public class Pair { private T first; private T last; public Pair(T first, T last) { this.first = first; this.last = last; } public T getFirst() { return first; } public T getLast() { return last; } } 类型参数

类型参数是用于定义泛型类、接口和方法时的占位符,表示某种类型。

在泛型中,中的 T 确实是自定义的,常见的类型参数有:

T:表示类型(Type)。E:表示集合元素(Element)。K``和 V`:分别表示键(Key)和值(Value)。N:表示数字(Number)。S, U, V等:用于多个类型参数的情况。

但是,这些都是约定俗成的,并不是强制的。你可以使用任何合法的字母或标识符作为泛型参数。

使用多个类型参数

public class Pair { private K key; private V value; public Pair(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; } }

在这个例子中,Pair类使用了两个类型参数K和V,分别表示键和值。

虽然可以使用任意字母作为类型参数,但使用有意义的字母(如T、E、K、V等)更有助于代码的可读性和理解。如果你的代码涉及多个类型参数,建议选择有意义的字母来表示不同的类型。

类型参数使用示例

定义一个泛型类 Box:

public class Box { private T content; public void setContent(T content) { this.content = content; } public T getContent() { return content; } }

使用这个泛型类:

Box stringBox = new Box(); stringBox.setContent("Hello"); String content = stringBox.getContent(); 通配符

通配符是用于实例化泛型类型时表示未知类型的占位符,用来表示不确定的类型,常见的有三种:

无界通配符:,表示任意类型。有界通配符(上界):是一个无界通配符,表示方法printBox可以接受任何类型的Box。

限定类型参数示例

有时候需要对类型参数进行限制,例如只允许某个类型及其子类:

public class NumberBox { private T number; public void setNumber(T number) { this.number = number; } public T getNumber() { return number; } }

在这个例子中,T被限定为Number类型及其子类。

总结:泛型是Java中强大的特性,通过参数化类型提高了代码的复用性和类型安全性。理解和合理使用泛型可以显著提升代码的质量和可维护性。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3