James Busby
James Busby

Reputation: 119

Java class that extends Kotlin base class cannot call internal methods of base

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

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

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:

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:

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.

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

Upvotes: 2

Views: 1470

Answers (1)

leonardkraemer
leonardkraemer

Reputation: 6813

The thing with the name is explained here in 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;

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

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

Upvotes: 2

Related Questions