泛型擦除之后,Comparable
public lib.Box(int) flags: (0x0001) ACC_PUBLIC
public int compareTo(lib.Box) flags: (0x0001) ACC_PUBLIC
public java.lang.String get() flags: (0x0001) ACC_PUBLIC
public lib.Box clone() flags: (0x0001) ACC_PUBLIC
public int compareTo(java.lang.Object) flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
public java.lang.Object get() flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
桥接方法 compareTo(Object) 的字节码:
Code:
0: aload_0
1: aload_1
2: checkcast #8 // class lib/Box
5: invokevirtual #37 // Method compareTo:(Llib/Box;)I
8: ireturn
Visible 里的方法(visibility bridge):
#7 = Methodref #2.#8 // lib/Hidden.hello:()V
#8 = NameAndType #9:#6 // hello:()V
#9 = Utf8 hello
public void hello();
flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
1: invokespecial #7 // Method lib/Hidden.hello:()V clone[] 返回 Object [bridge synthetic public volatile] 注解:[]
clone[] 返回 Box [public] 注解:[]
compareTo[Object] 返回 int [bridge synthetic public volatile] 注解:[Tag]
compareTo[Box] 返回 int [public] 注解:[Tag]
get[] 返回 Object [bridge synthetic public volatile] 注解:[]
get[] 返回 String [public] 注解:[]
getDeclaredMethods() 共 6 个;其中桥接方法 3 个;源码里写了 3 个方法(compareTo、get、clone),另外 3 个都是 javac 生成的桥接方法
getMethod("compareTo", Object.class) → bridge = true;getMethod("compareTo", Box.class) → bridge = false
反射调用桥接版本 compareTo(Object) = -1;调用真实版本 = -1
经桥接版本传入 String → InvocationTargetException,cause = ClassCastException: class java.lang.String cannot be cast to class lib.Box
经真实版本传入 String → IllegalArgumentException: argument type mismatch
Visible.getDeclaredMethods():hello [bridge synthetic public volatile],声明类 Visible
Visible.class.getMethod("hello").getDeclaringClass() = Visible,bridge = true 原始类型调用 compareTo("oops") → ClassCastException: class java.lang.String cannot be cast to class lib.Box
栈帧 0: lib.Box.compareTo(Box.java:4)
栈帧 1: Main.main(Main.java:20)
堆污染:List<Box> 里被塞了一个 String,Collections.sort → ClassCastException: class lib.Box cannot be cast to class java.lang.String
栈帧 0: java.lang.String.compareTo(String.java:142)
栈帧 1: java.util.ComparableTimSort.binarySort(ComparableTimSort.java:262)
String.class.getMethod("compareTo", Object.class).isBridge() = true(JDK 自己的 String 也有桥接方法)
通过接口 Supplier<String> 调用 get():box7
clone() 的返回类型是 Box,但 Object.clone() 的是 Object:Box 的 clone 桥接 + 真实共 2 个方法
hello from Hidden
hello from Hidden
Visible 继承自包私有类 Hidden:v.hello() 与反射 m.invoke(v) 都成功(没有 IllegalAccessException)