2017-09-18 20 views
0

推断通用超试图调用需要一个Class作为参数现有的Java代码科特林语法,我尝试代码沿着这科特林行:从亚型

package com.example 

//Acutally imported Java code in someone elses's library 
abstract class JavaCode<T> { 
    fun doTheThing(thing: Class<JavaCode<T>>) { 
     //Does work 
    } 
} 

//My code 
class KotlinCode : JavaCode<String>() { 
    fun startTheThing() { 
     doTheThing(KotlinCode::class.java) 
    }        //^Type inference failed. Expected type mismatch 
} 

但是,这并不与编译以下错误:

Type inference failed. Expected type mismatch: inferred type is Class<KotlinCode> but Class<JavaCode<String>> was expected 

所以我试图强行投(如this answer建议):

hello(GenericArgument::class.java as Class<Callable<String>>) 

但是,有一个警告:

Unchecked cast: Class<KotlinCode> to Class<JavaCode<String>> 

那么什么是使用正确的语法?是this有关?

+0

因为'赎回'='可赎回',你试图声明'类GenericArgument:可赎回'? – Stepango

+0

这只是将预期的类型不匹配改为'Class >'。 –

回答

0

你的代码有几个问题。

首先,Callable<String?>不等于Callable<String>Callable<String?>表示参数可以是Stringnull,但Callable<String>只有String

二,Class<GenericArgument>未执行Class<Callable<String>>,但是GenericArgument执行Callable<String>。他们是不同的。您可以将其更改为使用泛型。

private fun <T : Callable<String>> hello(callable: Class<T>) { 
    System.out.println(callable.toString()) 
} 

现在,通用参数受到Callable<String>的约束。

三,callable.toString()可能不会做你想做的。 callable.toString()将调用该类的toString()而不是对象,例如, class com.example.yourclass。如果你想打电话给对象toString()。这是正确的。

override fun call(): String { 
    hello(GenericArgument()) 
    return "value" 
} 

private fun <T : Callable<String>> hello(callable: T) { 
    System.out.println(callable.toString()) 
} 

此外,Kotlin允许传递函数作为参数或使用SAM作为接口。没有必要实施Callable

编辑:由于op更新了问题。

@Suppress("UNCHECKED_CAST") 
fun <T, U : JavaCode<T>> JavaCode<T>.doTheThing2(thing: Class<U>) { 
    doTheThing(thing as Class<JavaCode<T>>) 
} 
+0

我明白'String'和'String?'有区别。在那之后,也许我的例子有点失败。它实际上是一个我正在扩展的抽象Java类。我想要使​​用的方法是在基类上。这是别人的图书馆,使改变变得困难。这实际上不是一个“可调用”的;那只是为了提供一个相同问题的例子。我也意识到'callable.toString()'不是特别有用。再一次,这只是为了证明这一点。这听起来像我必须改变被调用者('hello'),但调用者('call')是我可以修改的位。 –

+0

@AlexTaylor Java在运行时没有通用元数据,所以通用转换可能导致错误。 – Joshua

+0

Kotlin没有提供防范的能力吗?基本上,在这种情况下,Java代码不能提供运行时类型的安全性,但Kotlin会给你一个警告?我用更接近真实代码的东西更新了代码。 –