Kotlin错误:“ public”函数公开其“ public / * package * /”返回类型参数

时间:2018-10-28 07:34:08

标签: java generics kotlin extends

我是Kotlin的新手,正在尝试使用该语言编写一些项目。 我正在使用Java库并在我的项目中从该库扩展一个类,并且看到此错误消息。

'public' function exposes its 'public/*package*/' return type argument FooSettings

我知道问题出在哪里,但我不确定如何在Kotlin中修复它,因为我仍在尝试熟悉Kotlin。 我可以看到Kotlin很聪明,只尝试返回扩展了FooSettings的类型。但是,问题是FooSettings仅在包公开的情况下存在,这意味着如果在我的Kotlin项目中,我将无法访问。

我对Kotlin泛型和inout的使用进行了一些研究,但无法解决问题。

在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

2 个答案:

答案 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){ ... }