假设我们有一个具有此类的第三方Java库:
//----------------------------------------------------------------------------------------
package foo;
public final class Functions {
public interface VoidFunc0 {
void call();
}
public interface VoidFunc1<T> {
void call(T t);
}
@SuppressWarnings("unchecked")
public static <T> NoOpFunc<T> noOp() {
return new NoOpFunc();
}
/*public*/ static final class NoOpFunc<T> implements VoidFunc0, VoidFunc1<T> {
@Override public void call() { /* deliberately no op */}
@Override public void call(T t) { /* deliberately no op */ }
}
}
//----------------------------------------------------------------------------------------
我们在Java应用程序中成功使用了它的Functions.noOp()
方法,但是当我们开始在Kotlin中重写它时,我们遇到了以下代码无法编译并给我们两个错误的问题:
//----------------------------------------------------------------------------------------
package bar
import foo.Functions
object KotlinApp {
@JvmStatic
fun main(args: Array<String>) {
/*
* Error:(XX, XX) Kotlin: Type inference failed: Not enough information
* to infer parameter T in fun <T : Any!> noOp(): Functions.NoOpFunc<T!>!
* Please specify it explicitly.
*/
callVoidFunc0(Functions.noOp()) // ERROR 1
/*
* Error:(XX, XX) Kotlin: Type Functions.NoOpFunc<Any!>! is inaccessible
* in this context due to: Functions.NoOpFunc<Any!>!
*/
callVoidFunc1(Functions.noOp()) // ERROR 2
}
fun callVoidFunc0(func0: Functions.VoidFunc0) {
func0.call()
}
fun callVoidFunc1(func1: Functions.VoidFunc1<Any>) {
func1.call("A")
}
}
//----------------------------------------------------------------------------------------
但以前用Java编写的相同代码编译并运行良好:
//----------------------------------------------------------------------------------------
package bar;
import foo.Functions;
public class JavaApp {
public static void main(String[] args) {
callVoidFunc0(Functions.noOp()); // OK
callVoidFunc1(Functions.noOp()); // OK
}
public static void callVoidFunc0(Functions.VoidFunc0 func0) {
func0.call();
}
public static void callVoidFunc1(Functions.VoidFunc1<Object> func1) {
func1.call("A");
}
}
//----------------------------------------------------------------------------------------
即使我们明确指定T
,类型推断也会失败。 <{1}}声明为NoOpFunc
时错误2消失,但错误1仍然存在。
答案 0 :(得分:4)
问题是Kotlin的一个错误。 以下是该问题的链接:https://youtrack.jetbrains.com/issue/KT-14499。请投票。
<强> UPD 强> 要解决这个问题,我们需要解决方法:
@JvmStatic
fun main(args: Array<String>) {
@Suppress("INACCESSIBLE_TYPE")
callVoidFunc0(Functions.noOp()) // (1)
@Suppress("INACCESSIBLE_TYPE")
callVoidFunc1(Functions.noOp<Any>()) // (2)
}
要修复(1)必须禁止编译警告,要修复(2) - 另外明确指定类型。