扩展Kotlin基类的Java类不能调用base的内部方法

时间:2021-07-25 20:06:15

I am experimenting with Kotlin on Android, with Android Studio, mixing it with some existing Java code, and I've come across a problem.

我在Android上试用Kotlin,使用Android Studio,将它与一些现有的Java代码混合,我遇到了一个问题。

I have a base class in Kotlin with a single method marked as internal:

我在Kotlin有一个基类,有一个标记为内部的方法:

package com.example.kotlin.hellokotlin

open class KotlinBaseClass
{
    internal fun doSomething()
    {
        println("Done something!")
    }
}

I then create a Kotlin class that extends KotlinBaseClass and calls the base class method:

然后我创建了一个Kotlin类,它扩展了KotlinBaseClass并调用了基类方法:

package com.example.kotlin.hellokotlin

class KotlinDerivedClass : BaseClass()
{
    fun doSomethingElse()
    {
        doSomething()
        println("Done something else!")
    }
}

This compiles and works fine.

这编译并正常工作。

If I now create a Java class that extends KotlinBaseClass instead, intended to be functionally identical to KotlinDerivedClass:

如果我现在创建一个扩展KotlinBaseClass的Java类,意图在功能上与KotlinDerivedClass相同:

package com.example.kotlin.hellokotlin;

public class JavaDerivedClass extends KotlinBaseClass
{
    public void doSomethingElse()
    {
        doSomething();
        System.out.println("Done something else!");
    }
}

I find that this class will not compile, because the method doSomething() cannot be resolved. If I remove the internal keyword from the declaration of doSomething() in KotlinBaseClass, everything works. All the classes are defined in the same package.

我发现这个类不会编译,因为方法doSomething()无法解析。如果我从KotlinBaseClass中的doSomething()声明中删除internal关键字,一切正常。所有类都在同一个包中定义。

Is this expected behaviour? A known issue with interoperability between Java and Kotlin?

这是预期的行为吗? Java和Kotlin之间的互操作性的已知问题?

1 个解决方案

#1


2  

The thing with the name is explained here in https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html

具有该名称的东西在https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html中有解释。

internal declarations become public in Java. Members of internal classes go through name mangling, to make it harder to accidentally use them from Java and to allow overloading for members with the same signature that don't see each other according to Kotlin rules;

内部声明在Java中公开。内部类的成员通过名称修改,使得更难以从Java中意外地使用它们,并允许根据Kotlin规则对具有相同签名的成员进行重载,这些成员彼此不能看到;

In your Java class you should be able to find the name by typing the first few characters and then alt + space to get the auto-completion. The full name of the function in your Java class is doSomething$nameOfYourModule

在Java类中,您应该能够通过键入前几个字符找到名称,然后使用alt + space来获取自动完成。 Java类中函数的全名是doSomething $ nameOfYourModule

Alternatively you can set doSomethingto protected and access it by its normal name.

或者,您可以将doSomething设置为protected并按其常规名称访问它。

#1


2  

The thing with the name is explained here in https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html

具有该名称的东西在https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html中有解释。

internal declarations become public in Java. Members of internal classes go through name mangling, to make it harder to accidentally use them from Java and to allow overloading for members with the same signature that don't see each other according to Kotlin rules;

内部声明在Java中公开。内部类的成员通过名称修改,使得更难以从Java中意外地使用它们,并允许根据Kotlin规则对具有相同签名的成员进行重载,这些成员彼此不能看到;

In your Java class you should be able to find the name by typing the first few characters and then alt + space to get the auto-completion. The full name of the function in your Java class is doSomething$nameOfYourModule

在Java类中,您应该能够通过键入前几个字符找到名称,然后使用alt + space来获取自动完成。 Java类中函数的全名是doSomething $ nameOfYourModule

Alternatively you can set doSomethingto protected and access it by its normal name.

或者,您可以将doSomething设置为protected并按其常规名称访问它。