ArrayList的get()方法为什么可以直接将Object数组返回成泛型里的类型?-灵析社区

CTang

ArrayList的get()方法为什么可以直接将Object数组返回成泛型里的T? 今天阅读ArrayList源码时,为什么可以直接在返回类型为泛型的方法里直接返回Object数组,而我自己定义的类里却需要强转? 以下是ArrayList源码 public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, Serializable { transient Object[] elementData; E elementData(int index) { return this.elementData[index]; } } 而我的代码却无法编译 ![image.png](https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20240925/c63ab85450564e8afb3417a2e24efbf0.png)

阅读量:150

点赞量:0

问AI
你这个代码是不是通过 IDE 里的 go to definition 看到的。 对 ArrayList ,这种方式看到的不是实际代码,而是通过反汇编得到的。 而对于这类 generic 函数,类型检查实际上貌似是在最终不再有 generic 类型的调用处发生的,而不是被调函数里。所以反汇编的代码里就看不到类型转换了。 但是实际代码,没有类型转化是无法通过编译的。 这应该是由于类型擦除,在 elementData 函数体是无法得到 E 具体是什么类型的,也就无法进行实际的转换。实际的转换要一直延迟到可以确定 E 的位置才能发生。 *** package foo; public class Generic { public T getObjectFoo() { return (T) new Object(); } } "javap -c Generic.class" Compiled from "Generic.java" public class foo.Generic { public foo.Generic(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."":()V 4: return public T getObjectFoo(); Code: 0: new #3 // class java/lang/Object 3: dup 4: invokespecial #8 // Method java/lang/Object."":()V 7: areturn } package foo; public class Foo { public void A() { final Generic g = new Generic(); final Integer i = g.getObjectFoo(); } } "javap -c Foo.class" Compiled from "Foo.java" public class foo.Foo { public foo.Foo(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."":()V 4: return public void A(); Code: 0: new #15 // class foo/Generic 3: dup 4: invokespecial #17 // Method foo/Generic."":()V 7: astore_1 8: aload_1 9: invokevirtual #18 // Method foo/Generic.getObjectFoo:()Ljava/lang/Object; 12: checkcast #22 // class java/lang/Integer !!!! 实际的类型检查(转换) 15: astore_2 16: return } 可以看到类型检查(转换)的代码是在 Foo.A 里,而不在 Generic.getInteger 里。所以如果是对 Generic.getInteger 进行反汇编,可能就看不到里面的类型转换了。