我是Kotlin的新手,正在尝试使用该语言编写一些项目。 我正在使用Java库并在我的项目中从该库扩展一个类,并且看到此错误消息。
'public' function exposes its 'public/*package*/' return type argument FooSettings
我知道问题出在哪里,但我不确定如何在Kotlin中修复它,因为我仍在尝试熟悉Kotlin。
我可以看到Kotlin很聪明,只尝试返回扩展了FooSettings
的类型。但是,问题是FooSettings
仅在包公开的情况下存在,这意味着如果在我的Kotlin项目中,我将无法访问。
我对Kotlin泛型和in
或out
的使用进行了一些研究,但无法解决问题。
在Kotlin项目中可以解决我遇到的错误吗?
这是Java库类的示例: 注意,我无法更改该库的实现。我必须使用此库并在Kotlin中对其进行扩展。
在我看来,以这种方式编写Java库并期望它会被重写是很奇怪的,但这又是一个问题。
import java.util.Collections;
import java.util.List;
public abstract class ClassA {
public List<FooBuilder<?>> getBuilder(Foo foo) {
return Collections.emptyList();
}
}
public class Foo {
}
public abstract class FooBuilder<U extends FooBuilder.FooSettings> {
// implementation of Class
abstract static class FooSettings {
// implementation of Class
}
}
通常,Java类会覆盖如下方法:
import java.util.List;
public class MyJavaClassA extends ClassA {
@Override public List<FooBuilder<?>> getBuilder(final Foo foo) {
// implementation
}
}
但是我试图用Kotlin编写,看起来像这样:提醒一下,该Kotlin依赖于Java库,无法访问包公共类。
class MyKotlinClassA : ClassA() {
override fun getBuilder(foo: Foo): MutableList<FooBuilder<*>> {
// implementation
}
}
这会导致错误
'public' function exposes its 'public/*package*/' return type argument FooSettings
答案 0 :(得分:1)
我认为“公开包”是指“私有包”吗?在您的示例中,FooBuilder.FooSettings
没有可见性修饰符,因此使用Java默认的包private。假设那就是你的意思...
您将能够在Kotlin代码中访问包私有类FooSettings
,但前提是您将该Kotlin代码放在与声明FooSettings
的包相匹配的包中。
您仍然会遇到相同的编译错误,但这不是因为您无法访问类型:这是因为您试图在比类型的声明更可见的上下文中使用它。也就是说,您正在尝试采用包私有类型,并将其用作公共方法签名的一部分,这是不允许的。要解决该问题,您需要将Kotlin类标记为internal
。
值得一提的是,internal
对于Kotlin来说意味着它在该模块中可见,而不在该软件包中可见。 here对此进行了更详细的说明。
答案 1 :(得分:1)
在我的情况下,由于从另一个Java文件导入kotlin类变量而出现此错误,该变量是由于Android Studio从Java到kotlin的自动转换而引发的。
我能够通过将java文件中变量的所有引用更改为其设置器和获取器来修复它。
例如:
// kotlin file
internal open class BubbleBaseLayout : FrameLayout {
var windowManager: WindowManager? = null
lateinit var viewParams: WindowManager.LayoutParams
// defined here
var layoutCoordinator: BubblesLayoutCoordinator? = null
// ...
}
// Java file
// This variable
if (layoutCoordinator != null) { ... }
需要更改为
// layoutCoordinator to getlayoutCoordinator everywhere
if(getlayoutCoordinator() != null){ ... }