kotlin t class.java_Kotlin使用Class调用Java方法 论据

小编典典

@edwin的答案是正确的,您遇到了XY问题,您实际上是在问错了什么。值得庆幸的是,您在执行此操作时遇到了一个错误,这导致您进入此处,@

edwin能够解释执行正确行为的替代方法。

每个Java绑定库都具有类似的模式(Class与类型引用相对)。因此,这是好东西,您可以在您的库中学习和查找,例如RestTemplate,Jackson,GSON等。实用程序类可能ParameterizedTypeReference在一个中,TypeReference在另一个中,TypeRef在另一个中,依此类推;但所有人都在做同一件事。

现在,对于任何想知道原始代码有什么问题的人 ,创建一个泛型擦除的类引用(例如Class语法)将是:

val ref = List::class.java

您会注意到没有办法表达列表中项目的通用类型。即使可以,它们也会由于类型擦除而被擦除。将此传递给绑定库就像说“

请为可能为空的java.lang.Object的列表 ”,但更糟。想象一下Map

List>,您现在在哪里丢失了所有可能反序列化的信息。

以下内容 无法 编译:

val ref = List::class.java //

错误消息可能更清楚地说:“ ::左侧仅允许没有通用参数的类 ”

并且您javaClass只能在实例上使用,因此,如果您碰巧拥有一个方便的列表…

val ref = listOf("one", "two", "three").javaClass

然后,您将得到一个擦除的类型Class,这再次是在这里使用错误的东西,但语法正确。

那么@edwin显示的代码实际上是做什么的呢?

通过创建具有超类型ParameterizedTypeReference的对象,代码可以解决此问题,因为即使删除了类型,任何类都可以通过的镜头看到其超类和接口中的泛型Type。例如:

val xyz = object : MySuperClass() {}

匿名类的该实例具有MySuperClass具有通用参数的超类SomeGenerics。因此,如果MySuperClass包含以下代码:

abstract class MySuperClass protected constructor() {

val type: Type = (javaClass.genericSuperclass as ParameterizedType)

.actualTypeArguments[0]

}

然后,您可以添加 .type到声明的末尾以访问此功能:

val typeOfSomeGenerics = object : MySuperClass() {}.type

现在,您将具有一些Type描述我们的SomeGenerics类的实现。这将是一个:

Class,ParameterizedType,GenericArrayType,TypeVariable,和WildcardType

通过了解和使用这些知识,一个进行数据绑定的库足以了解其工作。

Kotlin的生活更轻松:

在Kotlin中,编写扩展函数很容易,因此您不必重复执行此类代码。只需创建一个使用内联泛型的助手内联函数来传递类型并创建ParameterizedTypeReference:

inline fun typeRef(): ParameterizedTypeReference = object: ParameterizedTypeReference(){}

现在,您可以将@edwin的示例更改为:

val response = restTemplate.exchange(request, typeRef>())

2020-12-03

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值