假设我们有一个第三方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
,类型推断仍然会失败。当将NoOpFunc
声明为public
时,错误2消失了,但是错误1仍然存在。
Action0
不是泛型,因此用于Action1
、Action2
等。虽然这并没有回答你的问题。 - Dmitry Zaytsev