当前位置: 首页 > wzjs >正文

哈尔滨做平台网站平台公司哪家好中山排名推广

哈尔滨做平台网站平台公司哪家好,中山排名推广,能够做渗透的网站,北京企业名录一览表文章目录 泛型擦除泛型擦除的底层逻辑代码示例 为什么需要泛型擦除&#xff1f;泛型擦除带来的限制 桥接方法示例&#xff1a;编译器生成的桥接方法桥接方法的作用代码验证拓展 泛型擦除 泛型擦除的底层逻辑 代码示例 class Box<T> {private T content;public void se…

文章目录

  • 泛型擦除
    • 泛型擦除的底层逻辑
      • 代码示例
    • 为什么需要泛型擦除?
    • 泛型擦除带来的限制
  • 桥接方法
    • 示例:
    • 编译器生成的桥接方法
    • 桥接方法的作用
    • 代码验证
    • 拓展

泛型擦除

泛型擦除的底层逻辑

代码示例

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

擦除后的等价形式
编译器将 T 替换为 Object(因为没有指定边界):

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

在调用 getContent() 时,编译器会自动插入强制转换:

Box<String> box = new Box<>();
String content = (String) box.getContent(); // 隐含强制转换

为什么需要泛型擦除?

泛型擦除是 Java 为 向后兼容性(Backward Compatibility) 设计的关键机制,具体原因如下:

  1. 兼容旧版本代码

    • Java 在 5.0 版本(2004年) 引入泛型。
    • 泛型擦除让新代码(带泛型)和旧代码(无泛型)共享同一个类文件结构。例如:
    // 泛型代码(Java 5+)
    List<String> list = new ArrayList<>();
    // 非泛型代码(Java 1.4-)
    List rawList = new ArrayList();
    

    泛型擦除后,两者本质都是 List,从而保证旧代码无需修改即可在新 JVM 上运行。

  2. 避免 JVM 修改

    • 泛型擦除 无需修改 JVM 的底层机制。JVM 仍使用同样的字节码指令处理泛型和非泛型集合,极大降低了实现复杂度。
  3. 减少代码冗余

    • 如果泛型类型不擦除,List 和 List 会分别生成不同的类文件,导致 代码膨胀(Code Bloat)。
    • 擦除后,所有泛型实例共享同一个类文件,提升执行效率。

泛型擦除带来的限制

虽然泛型擦除带来兼容性,但也引入了一些限制:

  1. 无法使用原始类型参数
// 编译错误:不能使用基本类型作为泛型参数
List<int> list = new ArrayList<>();
  1. 运行时无法获取泛型类型信息
public void printType(List<String> list) {// 尝试通过反射获取泛型类型参数(无效)Type type = list.getClass().getGenericComponentType();System.out.println(type); // 输出: null(实际类型已被擦除)
}
  1. 无法创建泛型数组
// 编译错误:不能创建泛型数组
T[] array = new T[10]; 

桥接方法

示例:

父类与子类定义

// 泛型父类
public class Box<T> {private T value;public void set(T value) {this.value = value;}public T get() {return value;}
}// 子类指定具体类型参数为 String
public class StringBox extends Box<String> {@Overridepublic void set(String value) { // 重写父类方法,参数类型为 Stringsuper.set(value.toUpperCase());}@Overridepublic String get() { // 重写父类方法,返回类型为 Stringreturn super.get();}
}

问题

  1. 由于泛型擦除,Box 编译后的原始方法是:
    • set(Object value)(原 set(String value))
    • get() 的返回类型是 Object(原 String)
  2. StringBox 中的重写方法是 set(String) 和 get(): String,与父类擦除后的 set(Object) 和 get(): Object 方法签名不匹配。

这会导致多态性失效:通过 Box box = new StringBox() 调用 set 方法时,JVM 期望的签名是 set(Object),但 StringBox 只有 set(String)。

编译器生成的桥接方法

编译器会在 StringBox 类中插入两个桥接方法,确保方法重写和类型安全:

// (通过反编译字节码可见)
public class StringBox extends Box<String> {// 用户定义的显式重写@Overridepublic void set(String value) {super.set(value.toUpperCase());}@Overridepublic String get() {return super.get();}// ------------------------------------// 编译器生成的桥接方法(对用户不可见)// ------------------------------------// 桥接方法 1:兼容父类 `set(Object value)` public void set(Object value) {// 强制类型检查并调用实际方法 `set(String)` this.set((String) value);}// 桥接方法 2:兼容父类 `get()`public Object get() {// 调用实际方法 `get(): String` 并向上转型为 Objectreturn this.get();}
}

桥接方法的作用

  1. 保证方法重写的多态性
  • JVM 通过方法签名(方法名 + 参数类型)和返回类型确定方法分派。
  • 在泛型擦除后,父类与子类的方法签名不匹配,桥接方法充当中间层,确保父类引用能正确调用子类的具体方法。
  1. 强制类型安全
  • 桥接方法中会插入类型检查:
    public void set(Object value) {this.set((String) value); // 强制转换为 String
    }
    
  • 若传入非法类型(如 Integer),运行时会抛出 ClassCastException,避免了类型混乱。

代码验证

通过反射查看 StringBox 的桥接方法:

import java.lang.reflect.Method;public class BridgeMethodDemo {public static void main(String[] args) {for (Method method : StringBox.class.getDeclaredMethods()) {if (method.isBridge()) {System.out.println("桥接方法:" + method);}}}
}

输出结果:

桥接方法:public void StringBox.set(java.lang.Object)
桥接方法:public java.lang.Object StringBox.get()

拓展

  • 当通过父类类型调用 set(“hello”) 时,实际调用的是桥接方法 set(Object),它会转换类型并调用子类的 set(String)。

  • 但 直接通过子类调用 set(String) 时,JVM 直接调用子类方法,无需桥接方法。

    public class Main {public static void main(String[] args) throws Exception {// 场景1: 通过父类类型引用调用 set()Box<String> box = new StringBox();System.out.println("=== 通过父类调用 set() ===");box.set("hello");  // 调用实际上会经过桥接方法 set(Object)// 场景2: 直接通过子类类型调用 set()StringBox stringBox = new StringBox();System.out.println("\n=== 直接通过子类调用 set() ===");stringBox.set("world"); // 直接调用 set(String)}
    }
    
  1. 桥接方法的间接调用(父类引用场景)

    • 当通过 Box box = new StringBox() 调用 box.set(“hello”) 时,Box 类在泛型擦除后实际的方法签名是 set(Object)。
    • 桥接方法(子类中的 set(Object))会被触发,将参数强制转换为 String,然后调用子类的 set(String) 方法。
    • 输出中看到 StringBox.set 被调用,证实桥接方法成功转发到子类具体方法。
  2. 直接调用子类方法(无需桥接)

    • StringBox stringBox = new StringBox(); stringBox.set(“world”) 直接调用子类重写的 set(String) 方法。
    • JVM 直接选择与方法签名 set(String) 精确匹配的方法,无需桥接方法。
http://www.dtcms.com/wzjs/99318.html

相关文章:

  • 数据库做后台网站网站seo文章该怎么写
  • 手机网站判断跳转代码搜索引擎的使用方法和技巧
  • 小程序骗局开发报价seo工作流程
  • 中小微企业名录库上海野猪seo
  • 手游托在什么网站申请长春网站建设
  • 网站建设项目简介徐州网页关键词优化
  • 莱芜定制网站建设公司微信推广费用一般多少
  • 在哪个网站做游戏视频好百度推广销售话术
  • 网站制作月薪多少谷歌排名优化
  • wordpress视频自适应代码上海seo网站排名优化公司
  • 网站推广优化平台网站模版
  • 专门做网站需要敲代码么2023年3月份疫情严重
  • 建设部网站首页格式合同2024年重大政治时事汇总
  • 业网站建设做销售有什么技巧和方法
  • 台州城乡建设规划网站免费推广途径与原因
  • 唐山市住房城乡建设部网站主页广州今天刚刚发生的重大新闻
  • 网站黄页推广软件百度识图网页版在线使用
  • 腾讯网站建设推广在线培训课程
  • 天猫网站建设论文互联网营销的特点
  • 企业 手机门户网站家庭优化大师免费下载
  • 深圳做网站网络公司windows优化大师免费版
  • seo自动排名软件石家庄网站建设方案优化
  • wordpress 无法评论seo服务指什么意思
  • 怎么做原创动漫视频网站营销宣传策划方案
  • 做的很好的黑白网站青岛关键词优化seo
  • 一元云购手机网站建设网站关键字优化技巧
  • zencart外贸网站建设快速提升排名seo
  • 双德网站建设网搜网
  • 网站如何做移动网站seo优化是指
  • 帮别人做网站用织梦模板行吗网站seo关键词排名