【高阶Java开发秘籍】:掌握<? extends>与类型擦除,写出更安全的泛型代码

第一章:泛型擦除与通配符的深层原理

Java 的泛型机制在编译期提供类型安全检查,但在运行时通过类型擦除(Type Erasure)移除泛型信息。这一设计确保了与旧版本 JVM 的兼容性,但也带来了某些限制和潜在陷阱。

类型擦除的工作机制

在编译过程中,所有泛型类型参数被替换为其边界类型或 Object(若无显式边界)。例如,List<String> 被擦除为 List,而 T extends Comparable<T> 则被替换为 Comparable。

public class Box {
    private T value;
    
    public void set(T value) {
        this.value = value; // 编译后:this.value = (Object)value;
    }
    
    public T get() {
        return value; // 编译后:return (T)(Object)value;
    }
}
上述代码中,T 在字节码中被替换为 Object,并在必要时插入强制类型转换。

通配符与边界推断

通配符 ? 提供更灵活的子类型关系表达能力。通过上界(? extends Type)和下界(? super Type)限定,可控制泛型的协变与逆变行为。
  • ? extends Number:允许传入 Number 及其子类的泛型实例,适用于只读场景
  • ? super Integer:允许传入 Integer 的父类泛型实例,适用于写入操作
  • ?:无界通配符,表示任意类型,但访问时只能作为 Object 处理
通配符类型示例使用场景
上界通配符List<? extends Number>读取集合元素
下界通配符List<? super Integer>向集合添加元素
无界通配符Map<?, ?>通用类型处理
理解泛型擦除与通配符机制,有助于避免 ClassCastException 并编写更具弹性的泛型代码。

第二章:深入理解Java泛型类型擦除

2.1 类型擦除的基本机制与编译期行为

Java 的泛型在编译期通过类型擦除实现,泛型信息仅用于编译检查,不会保留到运行时。
类型擦除的编译过程
泛型类在编译后会替换所有类型参数为它们的上界(通常是 Object),并插入必要的类型转换指令。

public class Box<T> {
    private T value;
    public T getValue() { return value; }
}
上述代码会被编译为:

public class Box {
    private Object value;
    public Object getValue() { return value; }
}
编译器自动插入强制类型转换以保证类型安全。
桥接方法与多态支持
为保持多态性,编译器生成桥接方法。例如子类重写泛型方法时,会生成一个签名兼容的桥接方法,确保动态分派正确执行。
  • 类型参数在编译后完全消失
  • 边界类型决定擦除后的具体类型
  • 桥接方法保障继承体系完整性

2.2 擦除后字节码分析:从源码到.class文件

Java泛型在编译期通过类型擦除实现,源码中的泛型信息不会保留到运行时。编译器将泛型参数替换为限定类型(或Object),并在必要时插入强制类型转换。
类型擦除示例
public class Box<T> {
    private T value;
    public void set(T value) { this.value = value; }
    public T get() { return value; }
}
上述代码经编译后,T被擦除为Object,生成的字节码等效于:
public class Box {
    private Object value;
    public void set(Object value) { this.value = value; }
    public Object get() { return value; }
}
逻辑分析:编译器移除了泛型语法,确保JVM无需理解泛型。所有引用类型参数均被替换为Object,保证了向后兼容性。
字节码验证工具
可使用javap -v Box.class查看实际生成的字节码,确认泛型信息已不存在于.class文件中。

2.3 泛型桥接方法与多态调用的实现细节

Java泛型在编译期通过类型擦除实现,导致泛型方法重写时可能出现签名不一致的问题。为此,编译器生成桥接方法(Bridge Method)来确保多态调用的正确性。
桥接方法的生成机制
当子类重写父类的泛型方法时,类型擦除可能导致方法签名不同。编译器自动生成桥接方法以维持多态行为。

class Box<T> {
    public void set(T value) { }
}

class IntBox extends Box<Integer> {
    @Override
    public void set(Integer value) { }
}
上述代码中,IntBox.set(Integer) 经类型擦除后变为 set(Integer),而父类方法变为 set(Object)。编译器生成桥接方法:

public void set(Object value) {
    set((Integer) value);
}
该方法将 Object 参数转型后转发到具体实现,保证多态调用链完整。
调用流程分析
  • 运行时根据实际对象类型选择方法版本
  • 桥接方法作为转发入口,调用类型特化的方法
  • 保障了泛型继承体系下的动态分派一致性

2.4 类型擦除带来的运行时限制与规避策略

Java 的泛型通过类型擦除实现,导致泛型信息在运行时不可用。这限制了直接实例化类型参数或进行 instanceof 判断。
类型擦除的典型问题

public <T> T createInstance(Class<T> clazz) {
    try {
        return clazz.newInstance(); // 必须传入 Class 对象弥补类型信息丢失
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
由于类型擦除,T 在运行时无具体类信息,需显式传入 Class<T> 参数辅助反射创建实例。
常见规避策略
  • 传递 Class 对象以保留类型信息
  • 使用通配符和边界(? extends T)增强灵活性
  • 借助工厂模式封装对象创建逻辑

2.5 实践:利用反射突破类型擦除获取泛型信息

Java 的泛型在编译期会进行类型擦除,导致运行时无法直接获取泛型的实际类型。但通过反射机制结合 ParameterizedType 接口,可以在特定场景下恢复泛型信息。
获取字段的泛型类型
Field field = MyClass.class.getDeclaredField("list");
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
    ParameterizedType pt = (ParameterizedType) genericType;
    Type actualType = pt.getActualTypeArguments()[0];
    System.out.println(actualType); // 输出: class java.lang.String
}
该代码通过反射获取字段的泛型声明,并转换为 ParameterizedType 以提取实际类型参数。
常见应用场景
  • 序列化框架(如Gson)解析泛型字段
  • 依赖注入容器处理泛型Bean
  • ORM框架映射泛型集合属性

第三章:<? extends>通配符的语义与边界控制

3.1 上界通配符的声明与合法操作范围

在泛型编程中,上界通配符通过 ? extends T 的形式声明,表示类型参数可以是 T 或其任意子类型。这种声明方式增强了API的灵活性,尤其适用于只读数据结构的操作。
合法操作范围分析
使用上界通配符后,编译器仅允许安全的读取操作,禁止向集合写入非 null 值,因为具体类型未知。

List numbers = Arrays.asList(1, 2.5, 3L);
Number first = numbers.get(0); // 合法:读取安全
// numbers.add(4);            // 编译错误:无法确定具体类型
上述代码中,numbers 可引用包含 Integer、Double 等的列表,但不能添加元素,确保类型安全性。
常见应用场景
  • 定义通用数据处理方法,如求和、最大值等聚合操作
  • 实现跨继承体系的数据遍历逻辑

3.2 PECS原则在中的体现与应用

PECS原则与上界通配符的关系
PECS(Producer Extends, Consumer Super)是泛型设计中的核心原则。当一个集合用于“生产”数据,即从中读取元素时,应使用? extends T。这表示该集合可以持有T类型或其子类型的实例,确保取出的元素可安全地向上转型为T。
代码示例:使用实现多态读取

List<? extends Number> numbers = Arrays.asList(1, 2.5, 3L);
for (Number num : numbers) {
    System.out.println(num.doubleValue()); // 安全读取
}
上述代码中,List<? extends Number>作为**生产者**,只能读取Number类型对象,无法添加任何非null元素(防止类型不安全),体现了PECS中“Extends用于生产”的设计哲学。
  • ? extends T允许传入T或其子类的泛型集合
  • 增强API灵活性,支持多态参数传递
  • 写操作受限,仅能读取T类型对象

3.3 实践:设计安全的只读泛型容器API

在构建高并发系统时,设计线程安全且不可变的只读泛型容器至关重要。通过封装底层数据结构并暴露受控访问接口,可有效防止外部修改。
接口设计原则
遵循最小权限原则,仅提供查询类方法,如 Get、Contains 和 Size,避免暴露任何写操作。
Go语言实现示例

type ReadOnlyContainer[T any] struct {
    data map[string]T
    mu   sync.RWMutex
}

func (r *ReadOnlyContainer[T]) Get(key string) (T, bool) {
    r.mu.RLock()
    defer r.mu.RUnlock()
    val, ok := r.data[key]
    return val, ok
}
上述代码使用泛型 T 支持任意类型存储,sync.RWMutex 保证读操作的并发安全性,且无公开的写方法,确保只读语义。
访问模式对比
操作类型是否允许
读取元素✅ 是
添加元素❌ 否
删除元素❌ 否

第四章:结合类型擦除与<? extends>的最佳实践

4.1 编译时类型检查 vs 运行时类型安全陷阱

在静态类型语言中,编译时类型检查能有效捕获类型错误,提升代码可靠性。例如,在 Go 中:

var age int = "twenty" // 编译错误:cannot use "twenty" (type string) as type int
该代码在编译阶段即被拒绝,防止了潜在运行时崩溃。 然而,动态类型转换或接口使用可能绕过编译检查,引入运行时风险。如:

func main() {
    var x interface{} = "hello"
    num := x.(int) // panic: interface conversion: interface {} is string, not int
}
此处类型断言在运行时失败,引发 panic。应使用安全断言:

num, ok := x.(int)
if !ok {
    log.Fatal("x is not an integer")
}
检查阶段优势风险
编译时早期错误发现灵活性受限
运行时动态行为支持类型安全漏洞

4.2 泛型方法与通配符的协同设计模式

在Java泛型编程中,泛型方法与通配符的结合使用能够显著提升API的灵活性和类型安全性。
泛型方法的基础结构
泛型方法通过声明类型参数来支持多种类型的输入。例如:

public <T> void printList(List<T> list) {
    for (T item : list) {
        System.out.println(item);
    }
}
该方法接受任意类型的List,T为类型占位符,在调用时自动推断。
通配符增强兼容性
当需要处理泛型的子类型关系时,使用通配符?配合extends或super可扩展适用范围:
  • List<? extends Number>:接受Number及其子类的列表,如Integer、Double
  • List<? super Integer>:接受Integer或其父类的列表,适用于写入操作
PECS原则的应用
遵循“Producer-Extends, Consumer-Super”原则,合理选择通配符方向,确保集合读写安全,避免类型转换异常。

4.3 避免常见误用:add()、cast()与heap pollution

在泛型编程中,不当使用 add() 和类型转换可能导致 heap pollution,即集合中实际存储的对象类型与其声明的泛型类型不一致。
典型误用场景
  • 向泛型集合添加非兼容类型对象
  • 强制将原始类型集合转换为泛型类型
代码示例与分析

List<String> strings = new ArrayList<>();
List<?> rawList = strings;
((List) rawList).add(123); // heap pollution
String s = strings.get(0); // ClassCastException
上述代码通过未受检的转换绕过泛型检查,向字符串列表插入整数,导致运行时类型错误。编译器会发出警告,但不会阻止编译。
规避策略
始终使用泛型声明完整类型,避免原始类型转换;启用编译器警告并认真处理 unchecked cast 提示,可有效防止 heap pollution。

4.4 实践:构建类型安全的集合工具类库

在现代应用开发中,集合操作频繁且易出错。通过泛型与接口约束,可构建类型安全的工具类库,提升代码健壮性。
核心设计原则
  • 使用泛型确保输入输出类型一致
  • 通过函数式接口支持链式调用
  • 避免运行时类型转换异常
示例:类型安全的过滤方法
func Filter[T any](slice []T, predicate func(T) bool) []T {
    var result []T
    for _, item := range slice {
        if predicate(item) {
            result = append(result, item)
        }
    }
    return result
}
该函数接受任意类型的切片和判断函数,返回同类型切片。编译期即可验证类型匹配,避免运行时错误。参数 predicate 决定保留元素的逻辑,实现高内聚低耦合。

第五章:泛型高级议题与未来演进方向

类型推导与约束的深层优化
现代编译器在处理泛型时,已逐步引入更智能的类型推导机制。以 Go 1.18+ 的泛型系统为例,函数调用中可通过参数自动推导类型参数,减少显式声明:

func Map[T, U any](slice []T, f func(T) U) []U {
    result := make([]U, len(slice))
    for i, v := range slice {
        result[i] = f(v)
    }
    return result
}

// 调用时无需指定 T 和 U
doubled := Map([]int{1, 2, 3}, func(x int) int { return x * 2 })
泛型与反射的协同挑战
当泛型与反射共存时,类型信息可能在运行时丢失。解决方案之一是结合接口约束与类型断言:
  • 使用 constraints.Ordered 约束基础可比较类型
  • 通过结构体标签标记需反射处理的字段
  • 在泛型函数内部使用 reflect.TypeOf 安全获取元数据
未来语言设计趋势
主流语言正探索更高阶的泛型能力。下表对比了不同语言的演进方向:
语言当前特性未来提案
Rustconst 泛型generic associated types (GATs)
C#协变/逆变无栈协程与泛型内联
Go类型集合方法表达式泛型推导
实战:构建类型安全事件总线
利用泛型可实现编译期检查的事件系统:

type EventHandler[T any] func(T)

type EventBus struct {
    handlers map[reflect.Type][]interface{}
}

func (bus *EventBus) Publish[T any](event T) {
    for _, h := range bus.handlers[reflect.TypeOf(event)] {
        h.(EventHandler[T])(event)
    }
}
一文搞定 Java泛型 1.什么是泛型 Java在1.5之后加入了泛型的概念。泛型,即“参数化类型”。泛型的本质是为了参数化类型(将类型参数化传递)(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。 举个例子 List arrayList = new A... 阅读详情

相关推荐

Jetpack Compose Navigation实战:从基础到高级导航模式

本文全面解析Jetpack Compose Navigation在Android开发中的应用,从基础导航实现到高级模式(如单任务/单顶模式),涵盖参数传递、嵌套导航、深层链接等核心功能。通过实战代码示例展示如何优化导航性能,并与ViewModel、Hilt等架构组件整合,为开发者提供高效的Compose导航解决方案。

pz890123456的博客 373

Java泛型解惑之 extends T>和 super T>上下界限

&lt;? extends T&gt;和&lt;? super T&gt;是Java泛型中的“通配符(Wildcards)”和“边界(Bounds)”的概念。 &lt;? extends T&gt;:是指 “上界通配符(Upper Bounds Wildcards)” &lt;? super T&gt;:是指 “下界通配符(Lower Bounds Wildcards)” 一、为什么要用通配符...

ystyaoshengting的专栏 2万+

【过检测】2026调试级去虚拟化虚拟机成品

EternalBlaze调试级虚拟机是由恒烈开发的定制化VMware环境,适用于逆向工程、病毒分析等专业场景。该虚拟机基于Windows 10 1909专业版,预装Python/JDK等开发环境和逆向工具包,支持快照回溯功能。特色包括:一键去虚拟化方案、双机调试支持、驱动开发环境等。适用场景涵盖CTF竞赛、软件调试、病毒行为分析等,但不支持DX12游戏和视频盗录。使用前需按步骤关闭安全中心、安装特定VMware版本并执行去虚拟化操作。虚拟机提供基础版和逆向调试增强版两种配置,均预装必要工具链。(149字)

Heng_lie的博客 2672

Java之泛型

泛型类,泛型方法,泛型上界,通配符上界,通配符下界。

m1879254的博客 2万+

FastAdmin框架Token验证实战:从登录到API调用的完整流程

本文详细解析了在FastAdmin框架中实现Token验证的完整流程,从数据表设计、登录接口签发Token,到核心验证中间件的编写与路由配置,并探讨了在业务API中的调用与安全实践。内容涵盖Token生成策略、有效期管理及安全增强措施,为开发者提供了一套可落地的API身份验证解决方案。

nnn11的博客 917

STorM BGC V1.31硬件+SimpleBGC固件:从零搭建三轴云台开发环境(Keil+JLink避坑指南)

本文详细介绍了如何从零搭建STorM BGC V1.31硬件+SimpleBGC固件的三轴云台开发环境,涵盖硬件连接、Keil+JLink开发工具配置、固件编译与烧录等关键步骤,并提供了常见问题的解决方案和调试技巧,帮助开发者快速上手三轴云台开发。

weixin_28693683的博客 380

Java 基础之泛型:类型安全的保障与灵活运用

泛型(Generics)简单来说,就是允许在定义类、接口和方法时使用类型参数。这些类型参数在使用时会被具体的类型所替代。例如,我们常见的集合类ArrayList就是一个泛型类,它的定义形式是,这里的E就是类型参数,在实际使用中,我们可以指定E为StringInteger等具体类型,如。泛型是 Java 中一个非常强大的特性,它在类型安全、代码复用和可读性方面都有着显著的优势。通过合理地运用泛型,我们可以编写更加健壮、高效和易于维护的 Java 代码。

qq_25699299的博客 3134

Python全栈入门到实战【AI实战篇 01】DeepSeek官方API全流程实战,第一个AI项目前置必备

文章摘要 本文介绍了基于DeepSeek API开发智能助手的前期准备和基础调用流程。内容涵盖: 前期准备:访问DeepSeek官网、完成账号注册与实名认证。 API Key获取:充值并创建API Key,强调密钥安全保存的重要性。 查阅文档:定位官方接口文档中的Python调用示例。 环境配置:安装openai依赖包,配置环境变量存储API Key。 代码编写:使用Python调用DeepSeek API实现基础对话功能。 调试与验证:解决常见问题,确保API调用成功。 适合零基础开发者跟随操作,快速入门

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 3738

Java基础27-Java 泛型:泛型擦除原理与通配符实战(? extends vs ? super)

Java泛型擦除与通配符实战解析 本文深入探讨Java泛型的核心机制——类型擦除,并重点解析通配符? extends与? super的使用场景。主要内容包括: 泛型基础:通过类型参数实现代码复用和类型安全 类型擦除原理:运行时泛型信息被擦除,替换为边界类型或Object 通配符详解: 无界通配符?的读取限制 ? extends T(生产者)支持安全读取但禁止写入 ? super T(消费者)支持安全写入但限制读取类型 文章通过代码示例验证类型擦除现象,并解释PECS原则(Producer-Extends,

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

手把手教你学simulink(57.3)--电励磁同步电动机场景示例:基于Simulink的自适应控制(Adaptive Control)电励磁同步电动机

目录基于Simulink的自适应控制(Adaptive Control)电励磁同步电动机项目实例1. 项目背景2. 系统架构2.1 电励磁同步电动机模型2.2 三相逆变器模型2.3 自适应控制器(Adaptive Controller)2.4 系统框图3. 模型设计3.1 创建Simulink模型3.2 自适应控制(Adaptive Control)设计3.3 仿真环境搭建4. 参数优化4.1 自动调优5. 实际应用案例5.1 工业驱动系统5.2 风力发电系统6. 结论需求分析电励磁同步电动机(Electr

MHD0815的博客 505

电源芯片MPQ3431A

MPQ3431A是一款具有宽输入范围的固定频率为450kHz的高度集成的升压转换器,其输入电压低至2.7V,采用恒定关断时间(COT)的控制拓扑,可提供快速的瞬态响应。芯片支持通过MODE管脚配置PSM(pulse-skip mode)、FCCM(forced continuous conduction mode)和USM(ultrasonic mode);还支持通过电流限制配置来达到精确的过流保护;同时芯片欠压保护(UVLO)和过温保护(OTP)。MPQ3431A采用QFN-13(3mmx4mm)封装。保

qflook的博客 1560

【Java学习】泛型

执行操作的一直都是Object类的似复刻变量,外界引用进来都是向上转型成Object类似复刻变量引用进来的,它通过编译类型检查指定确定了使用进入此泛型类变量里向上转型为Object类的似复刻变量的原下子类类型,对已知其下原子类类型的Object类似复刻变量在作为此泛型类变量里方法返回值处的对应去外部调用它处插入强转能对应向下转型回已知原子类类型的指定引用回来在外部,这样就实现了泛型类变量内部用所有类统一能用的Object父类来共用,外部不同类的使用处又能对应针对到各自不同的外部引用类

Brookty的博客 1526

Arduino、ESP32驱动BMP390L数字大气压传感器(压力传感器)

BMP390L是一款博世新研发的工业级专用数字气压传感器,具有极高的温度稳定性、低漂移、低功耗。

不脱发的程序猿 2009

Java泛型中通配符的使用详解

?extends T>确定了上界为T,那么获取值时类型一定是T或T的父类,但赋值时由于不能确定具体是T或者T的某个子类而赋值失败。

小鲁蛋的博客 8197

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Java泛型详解:为什么使用泛型?如何使用泛型?

大家好!,今天我将为大家介绍一个非常有趣的话题——泛型。作为Java语言中的一项重要特性,泛型可以让我们编写更加通用和灵活的代码。无论您是刚入门Java编程,还是已经有一定经验的开发者,了解泛型都对您的编程能力有所帮助。本文将深入探讨泛型的实现原理和本质,帮助您更好地理解并应用泛型。现在就让我们一起来探索吧!

沉淀所学,分享所思,让热爱与成长同行。商务记录AI实战经验,助力开发者快速成长。 热爱AI,希望做出有影响力的技术成果。 技术点亮生活,分享连接价值与机会。 专注AI落地实战,陪你走好技术每一步。 8381

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

深入理解Java泛型:类型擦除、通配符PECS原则与实践

摘要:本文深入探讨Java泛型机制,从类型擦除原理到PECS实践应用。首先分析泛型解决原始类型安全问题的价值,揭示类型擦除在编译期的运作机制及其限制。重点解析通配符的三种形态(extends/super/?)和PECS(Producer-Extends, Consumer-Super)原则,通过流程图和集合拷贝案例展示类型安全设计方法。最后通过构建类Stream的数据处理框架实战,演示如何设计生产者接口(extends)、消费者接口(super)和转换器,实现灵活且类型安全的API。文章强调泛型在编译时类型

七夜zippoe的博客 1131

【面试】泛型的类型擦除

本系列为大厂面试题系列的相关笔记,如有误,欢迎大家指正。 前言 – Java 泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,但有一点需要注意:Java 的泛型在编译器有效,在运行期被删除,也就是说所有泛型参数类型在编译后都会被清除掉,看下面一个列子,代码如下: public class Foo { public void listMethod(List<String> stringList){ } public void listMethod(.

weixin_51656605的博客 2787

java参数传入泛型类型_java泛型的那些事

学习泛型的理由首先明确为什么需要学习泛型?个人觉得至少有三个理由:1、使用泛型可以让你在声明类(或者创建方法)的时候不着急立即去指定它的类型,而是等到你实例化对象(或者方法调用)的时候才明确它的类型;2、避免通过使用Object类型来泛指java对象时,因类型强制向下转型时发生错误;3、可以毫无障碍的阅读Java相关源码。你经常遇到诸如Comparator super E> comparat...

weixin_28931449的博客 9408

java中泛型浅析——泛型擦除及extends和super通配符

文章目录1. 泛型的定义2. 泛型集合 1. 泛型的定义 先看一段维基百科上对Java中范泛的定义: Generics are a facility of generic programming that were added to the Java programming language in 2004 within version J2SE 5.0. They were designed to extend Java's type system to allow "a

weixin_41558411的博客 703

Java泛型

在Java5之前一个list啥都往里装,字符串、数字、对象,简直就是个大杂烩,自由是自由了,但麻烦也来了。首先在取数据的时候,你必须手动强转,其次,最要命的你要是记错了,把一个数字当成字符串来取了,编译的时候啥事没有,一运行就炸了,所以为了解决这个问题,泛型闪亮登场。加上泛型之后,它就像一个类型保安在编译期的时候就帮你检查了,这样以来取数据的时候也不用你手动强转了,代码又干净又安全。类型安全:把运行期的错误提前到了编译期代码重用。

2301_81354580的博客 1333

Java泛型 extends关键字设置边界

本文主要介绍在泛型定义中的< >中的占位符如何配合extends关键字使用,形如<T extends Integer>。泛型定义存在于这三种形式中:泛型类、泛型接口、泛型方法。 一般的泛型定义中的<T>,相当于<T extends Object>,而类型擦除则会将类型参数擦除成T的上界,即Object。则在泛型定义中作为T类型的对象可以调用Object的函数和属性。 使用了extends的泛型定义中的<T extends Integer>,其上界已被明显定义了,此时会将类型参数擦除成Integer。则在泛

anlian523的博客 2606

Java类型迷思:深度解析 List<?>, List<Object>, List 与泛型擦除的真相

特性List(原始类型)List<?(无界通配符)元素类型无类型信息 (视为 Object)明确是Object未知的某种特定类型添加元素允许添加任何类型对象允许添加任何类型对象禁止添加除null外的任何对象获取元素返回Object(需强转)返回Object(需强转)返回Object(安全)类型安全性 (编译时)最低,易引发运行时错误较低,读取需小心最高(写入被限制)赋值灵活性可接受任何List只能接受可接受任何参数化的List主要用途兼容遗留代码 (不推荐)明确需要存储多种类型对象。

2501_92427750的博客 1151

Java基础——泛型之通配符与类型擦除

Java基础——泛型之通配符与类型擦除 一、通配符?   Java泛型的通配符有三种形式,但究其根本只有"?“这一种形式,其他两种形式都是由”?"衍生出来的。   1、?:可以接收任意类型——只能作用于方法上,不能修改值     表示参数可以接收任意类型的泛型类,只能取得类中数据,不能修改数据,因为类型不确定,无法设置确定类型。(只知道是个泛型,连具体是什么类都不知道,肯定不能修改set值)   ...

xiaoaxiao 566

吃透 Java 泛型:从原理到实战,告别类型转换的烦恼

本文深入探讨了Java泛型的核心概念与应用。泛型作为JDK5引入的参数化类型特性,解决了类型安全、代码冗余等问题。文章从泛型定义入手,对比了非泛型集合的缺陷,展示了泛型在类型检查和代码简洁性上的优势。重点解析了泛型类/接口、泛型方法和通配符三大语法:通过GenericContainer示例演示泛型类实现;以printArray方法说明泛型方法的定义;详细介绍了无界通配符<?>、上界<? extends T>和下界<? super T>通配符的使用场景与限制。

qq_59219765的博客 1098

Java泛型 extends,super和通配符的理解

1.java泛型的特点 通常情况下,一个编译器处理泛型有两种方式:      1.Code specialization。在实例化一个泛型类或泛型方法时都产生一份新的目标代码(字节码or二进制代码)。例如,针对一个泛型list,可能需要 针对string,integer,float产生三份目标代码。      2.Code sharing。对每个泛型类只生成唯一的一份目标代码;该泛型类的所有

The Void 2082

一文搞懂Java泛型

Java中的泛型想必大家都不陌生,我们在创建使用 ArrayList 数组的时候,往往需要传递一个明确的参数类型。然而,往往大多数程序员对泛型的理解也仅仅局限在限制类型,以及查看源码时对一大堆泛型类和泛型方法的使用不明觉厉。迟迟没有下定决心和花时间去了解。

qq_32403767的博客 928
上一篇: Java NIO Channel vs 传统IO:大规模文件传输效率对比实测(数据惊人)
下一篇: 为什么你的TreeMap排序总是出错?,一文解决Comparator所有坑
FuncInk
博客等级 码龄1年 157粉丝 1975原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值