栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

3分钟快速搞懂Java的桥接方法,mybatisplus分页原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

3分钟快速搞懂Java的桥接方法,mybatisplus分页原理

public class Child extends Parent {

@Override

Integer get() {

return 1;

}

}

Child类重写其父类Parent的get方法,Parent的get方法返回类型为Number,而Child类中get方法返回类型为Integer。

将这段代码进行编译,再反编译:

javac Child.java

javap -v -c Child.class

结果如下:

public class Child extends Parent

…省略部分结果…

java.lang.Integer get();

descriptor: ()Ljava/lang/Integer;

flags:

Code:

stack=1, locals=1, args_size=1

0: iconst_1

1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

4: areturn

LineNumberTable:

line 5: 0

java.lang.Number get();

descriptor: ()Ljava/lang/Number;

flags: ACC_BRIDGE, ACC_SYNTHETIC

Code:

stack=1, locals=1, args_size=1

0: aload_0

1: invokevirtual #3 // Method get:()Ljava/lang/Integer;

4: areturn

LineNumberTable:

line 1: 0

从上面的结果可以看到,有一个方法java.lang.Number get(), 在源码中是没有出现过的,是由编译器自动生成的,该方法被标记为ACC_BRIDGE和ACC_SYNTHETIC,就是我们前面所说的桥接方法。

这个方法就起了一个桥接的作用,它所做的就是把对自身的调用通过invokevirtual指令再调用方法java.lang.Integer get()。

**编译器这么做的原因是什么呢?**因为在JVM方法中,返回类型也是方法签名的一部分,而桥接方法的签名和其父类的方法签名一致,以此就实现了协变返回值类型。

类型擦除

泛型是Java 1.5才引进的概念,在这之前是没有泛型的概念的,但泛型代码能够很好地和之前版本的代码很好地兼容,这是为什么呢?

这是因为,在编译期间Java编译器会将类型参数替换为其上界(类型参数中extends子句的类型),如果上界没有定义,则默认为Object,这就叫做类型擦除。

当一个子类在继承(或实现)一个父类(或接口)的泛型方法时,在子类中明确指定了泛型类型,那么在编译时编译器会自动生成桥接方法,例如:

public class Parent {

void set(T t) {

}

}

public class Child extends Parent {

@Override

void set(String str) {

}

}

Child类在继承其父类Parent的泛型方法时,明确指定了泛型类型为String,将这段代码进行编译,再反编译:

public class Child extends Parent

…省略部分结果…

void set(java.lang.String);

descriptor: (Ljava/lang/String;)V

flags:

Code:

stack=0, locals=2, args_size=2

0: return

LineNumberTable:

line 5: 0

void set(java.lang.Object);

descriptor: (Ljava/lang/Object;)V

flags: ACC_BRIDGE, ACC_SYNTHETIC

Code:

stack=2, locals=2, args_size=2

0: aload_0

1: aload_1

2: checkcast #2 // class java/lang/String

5: invokevirtual #3 // Method set:(Ljava/lang/String;)V

8: return

LineNumberTable:

line 1: 0

从上面的结果可以看到,有一个方法void set(java.lang.Object), 在源码中是没有出现过的,是由编译器自动生成的,该方法被标记为ACC_BRIDGE和ACC_SYNTHETIC,就是我们前面所说的桥接方法。

这个方法就起了一个桥接的作用,它所做的就是把对自身的调用通过invokevirtual指令再调用方法void set(java.lang.String)。

**编译器这么做的原因是什么呢?**因为Parent类在类型擦除之后,变成这样:

写在最后

还有一份JAVA核心知识点整理(PDF):JVM,JAVA集合,JAVA多线程并发,JAVA基础,Spring原理,微服务,Netty与RPC,网络,日志,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算…

DF):JVM,JAVA集合,JAVA多线程并发,JAVA基础,Spring原理,微服务,Netty与RPC,网络,日志,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算…

[外链图片转存中…(img-USKPWd0f-1647439980735)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/770831.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号