hlu*_*kyi 5 java generics jvm kotlin
我正在调查创建代理对象的库是如何工作的,特别是我想了解它们如何从声明的方法中获取类型.例如Android的流行库 - Retrofit:
interface MyService {
@GET("path")
Call<MyData> getData();
}
Run Code Online (Sandbox Code Playgroud)
我很困惑 - 如何才能从这个界面获得正确的MyData类而不是原始对象?我的理解类型擦除的原因将删除放置在通用大括号内的任何信息.
我写了一些测试代码,令我惊讶的是从这样的代码获取类型真的很容易:
@org.junit.Test
public void run() {
Method[] methods = Test.class.getDeclaredMethods();
Method testMethod = methods[0];
System.out.println(testMethod.getReturnType());
ParameterizedType genericType = ((ParameterizedType) testMethod.getGenericReturnType());
Class<Integer> clazz = (Class<Integer>) genericType.getActualTypeArguments()[0];
System.out.println(clazz);
}
interface Test {
List<Integer> test();
}
Run Code Online (Sandbox Code Playgroud)
它看起来有点脏,但它的工作和打印Integer.这意味着我们在运行时有类型.此外,我已经阅读了有关匿名类的另一个脏技巧:
System.out.println(new ArrayList<Integer>().getClass().getGenericSuperclass());
Run Code Online (Sandbox Code Playgroud)
AbstractList<E>这段代码打印原始
System.out.println(new ArrayList<Integer>() { }.getClass().getGenericSuperclass());
Run Code Online (Sandbox Code Playgroud)
打印ArrayList<Integer>.
这并不是让我困惑的最后一件事.在Kotlin中有一些具体的泛型,在编译时看起来像是一些黑客,但我们可以轻松地从泛型中获取类:
inline fun <reified T> test() {
print(T::class)
}
Run Code Online (Sandbox Code Playgroud)
而现在我完全混淆了类型擦除机制.
new ArrayList<Integer>呢?更新: 4.如何在Kotlin中使用具体化的泛型以及为什么这样的酷事不能用Java实现?
这里解释了如何使用仿制药.@Mibac
您只能将reified与内联函数结合使用.这样的函数使得编译器将函数的字节码复制到每个使用函数的地方(函数被"内联").当您使用reified类型调用内联函数时,编译器会知道用作类型参数的实际类型,并修改生成的字节码以直接使用相应的类.因此,像myVar这样的调用是T变为myVar是String,如果类型参数是String,则在字节码和运行时.
\n\n\n有人可以解释一下,为什么有时它包含信息,有时不包含信息?
\n
在 jvm 级别有一个Signature 属性:
\n\n\n\n\n记录在 Java 编程语言中声明使用类型变量或参数化类型的类、接口、构造函数、方法或字段的签名 (\xc2\xa74.7.9.1)。
\n
您可能想要拥有它的原因之一是,例如,编译器需要知道some_method来自预编译some.class(来自第三方some.jar)的参数的实际类型。在这种情况下,假设该方法Object可能会违反编译时的假设some.class,并且您无法调用some_method以类型安全的方式进行调用。
\n\n\n为什么匿名类保留泛型类型并且不进行类型擦除?
\n
你打电话时:
\n\nSystem.out.println(new ArrayList<Integer>().getClass().getGenericSuperclass());\nRun Code Online (Sandbox Code Playgroud)\n\n...没有任何内容是根据jvm 类来定义的,而:
\n\nSystem.out.println(new ArrayList<Integer>() { }.getClass().getGenericSuperclass());\nRun Code Online (Sandbox Code Playgroud)\n\n...实际上在jvm 级别上定义了类,尽管在java 语言级别上是匿名的。
\n\n这就是为什么反射对于这些情况给出不同结果的原因。
\n\n\n\n\n\n\n为什么 Java 中泛型没有以正常方式实现?是的,我读到它可能会破坏与以前版本的兼容性,但我想了解如何实现。为什么泛型返回类型不会破坏任何东西,但新的 ArrayList 会破坏?
\n
\n\n\n具体化泛型在 Kotlin 中如何工作以及为什么这么酷的东西不能在 Java 中实现?
\n
我认为你不能对这些问题给出不基于观点的客观答案。此外,我建议拆分或缩小您的问题范围。
\n| 归档时间: |
|
| 查看次数: |
230 次 |
| 最近记录: |