Java Base —— 泛型

泛型,通用类型

<T>
### Java 技术详解 #### 什么是Java是一种允许开发者在定义类、接口和方法时指定类参数的技术。通过这种方式,可以创建可重用的代码组件,同时保持类安全性和灵活性。 然而,在 Java 中实现的被称为 **伪**,因为它的设计基于一种机制——**类擦除**[^1]。这意味着在运行时,所有的信息会被移除,从而使得不同类实例共享相同的字节码结构。 --- #### 类擦除的工作原理 考虑以下代码片段: ```java @Test public void test() { List<String> stringList = new ArrayList<>(); stringList.add(""); List<Integer> integerList = new ArrayList<>(); integerList.add(1); System.out.println(stringList.getClass() == integerList.getClass()); } // 输出结果:true ``` 尽管 `stringList` 和 `integerList` 声明为不同的 (`List<String>` 和 `List<Integer>`),但在运行时它们的实际类均为 `ArrayList`。这是因为编译器会在编译阶段执行类擦除操作,将所有信息替换为其对应的原始类 (raw type),即 `List<?>` 被转换成普通的 `List`。 这种行为虽然简化了 JVM 对的支持需求,但也带来了一些局限性,例如无法在运行时获取具体的信息。 --- #### 如何编写方法? 为了提高代码的通用性,可以通过引入方法来支持多种数据类的操作。以下是方法的基本语法及其应用示例: ```java public class TestMethod<U> { // 定义一个简单的方法 public <T, S> T testMethod(T t, S s) { return t; } public static void main(String[] args) { TestMethod<String> method = new TestMethod<>(); String result = method.testMethod("Hello", 123); System.out.println(result); // 输出: Hello } } ``` 上述例子展示了如何在一个非类中声明并调用方法。注意,即使该类本身不是类,仍然能够包含方法[^2]。 另外,如果需要在静态上下文中使用,则必须显式地为方法添加独立的类参数列表 `<T>` 或其他占位符名称(如 E、K、V)。这与成员变量或实例方法中的处理方式有所不同。 --- #### 类的设计模式 除了单独的方法外,还可以构建整个基于的类体系。下面是一个典的案例说明: ```java public class Animal<T, U> { private T value; public Animal(T value) { this.value = value; } // 提供一个静态方法 public static <T> T getLastElement(T... elements) { if (elements.length == 0) throw new IllegalArgumentException(); return elements[elements.length - 1]; } // 获取第一个属性值 public T getValue() { return value; } public static void main(String[] args) { Integer lastInt = Animal.getLastElement(1, 2, 3); System.out.println(lastInt); Double lastDouble = Animal.<Double>getLastElement(1.1, 2.2, 3.3); System.out.println(lastDouble); } } ``` 在此处可以看到两种形式的表达: 1. 动态绑定到具体对象上的字段类; 2. 静态环境中独立存在的函数签名约束条件[^3]。 --- #### 上界通配符的应用场景 当希望某个集合只接收特定基类或者其子类的对象作为元素时,可以利用上界通配符 `<? extends BaseClass>` 来限定范围。如下所示: ```java public static void process(List<? extends Number> list) { for (Number num : list) { double dValue = num.doubleValue(); // 可读取数值 } } process(Arrays.asList(1, 2, 3)); // 正确 process(Arrays.asList(1L, 2L, 3L)); // 错误,Long 不属于 Number 子集 ``` 这里强调的是,“?” 表达了一种不可变性的概念 —— 即使容器内部存储着某种派生自目标父级的数据项,也不能向其中新增任何实体,除非明确知道确切的目标类别[^4]。 --- #### 总结 综上所述,Java 提供了一个强大的工具包用于增强应用程序的安全性和效率;但由于其实现依赖于类擦除策略,因此存在一定的限制。理解这些特性有助于更好地运用这一功能解决实际开发过程遇到的各种挑战。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值