Java code that cannot be used from Kotlin (for in-house study sessions)


The code I was really into

Desk.java


package library_package;

abstract class BaseDesk {
    public enum Color { BLUE, ORANGE }
}

public class Desk extends BaseDesk {
    private Color color;

    public Desk(Color color) {
        this.color = color;
    }
}

Of course, using such a Java implementation from Java works well.

java


new Desk(Desk.Color.BLUE);

When used from Kotlin, I get a Compile Error.

kotlin


Desk(Desk.Color.BLUE) // Unresolved reference: Color

kotlin


import library_package.BaseDesk // Cannot access 'BaseDesk': it is package-private in 'library_package'

Desk(BaseDesk.Color.BLUE) // Cannot access 'Color': it is public in 'BaseDesk'

How to avoid

To solve this problem (maybe?), A static method called getColorEnum () was prepared.

Desk.java


package library_package;

abstract class BaseDesk {
    public enum Color { BLUE, ORANGE }

    public static Color getColorEnum(String name) {
        return Color.valueOf(name);
    }
}

kotlin


@Suppress("INACCESSIBLE_TYPE") //suppress warning is necessary
Desk(Desk.getColorEnum("BLUE")) //I was able to put a Color instance in the Desk constructor

Why do I get an error / not?

Looking at what kind of case causes an error ...

Foo.java


class BaseFoo {
    public static int i = 0;

    public static int inc() {
        return ++i;
    }

    public static class FooFoo {
        public static int j = 0;
    }
}

public class Foo extends BaseFoo {}

java


int foo_i = Foo.i;
int foo_inc = Foo.inc();
int foo_foo_j = Foo.FooFoo.j;

kotlin


val foo_i = Foo.i
val foo_inc = Foo.inc()
val foo_foo_j: Int = Foo.FooFoo.j // Unresolved reference: FooFoo

Kotlin doesn't seem to be able to access the static inner class of the super class. I took a quick look at the underlying language specifications, but didn't understand.


Why could it be used as a method return value?

Java seems to be able to define an originally invisible class as a return value.

public class Bar {
    public static InternalBar getBar() {
        return new InternalBar();
    }

    private static class InternalBar extends Bar {}
}

Bar bar = Bar.getBar(); // OK

You can't do this with Kotlin.

open class Baz {
    companion object {
        fun getInternalBaz(): InternalBaz { // 'public' function exposes its 'private' return type InternalBaz
            return InternalBaz()
        }

        fun getBaz(): Baz { // OK
            return InternalBaz()
        }
    }
    private class InternalBaz : Baz()
}

What is INACCESSIBLE_TYPE warning?

There is a problem that the behavior of Kotlin Compiler, which causes an error when it cannot be referenced, does not match the Java specifications as described above and cannot be compiled. Currently, it is set to Warning instead of Compile Error, but it will be properly accessed in the future. It seems that it will be changed again so that it will be a compile error only when it is not possible.

See https://youtrack.jetbrains.com/issue/KT-11398.


What if getColorEnum () is not provided on the Library side?

You can create your own Utility Method in Java.

DeskColorResolver.java


import library_package.Desk;

public class DeskColorResolver {
    public static Desk.Color getColor(String name) {
        return Desk.Color.valueOf(name);
    }
}

kotlin


val desk = Desk(DeskColorResolver.getColorEnum("BLUE"))

Can be written. Is this really the correct answer ...?


thanks!

Recommended Posts

Java code that cannot be used from Kotlin (for in-house study sessions)
Java 14 new features that could be used to write code
Note that system properties including JAXBContext cannot be used in Java11
Memo for migration from java to kotlin
[Java] Variables declared inside the `for statement` cannot be used outside the` for statement block`
Technology excerpt that can be used for creating EC sites in Java training
[Java] Scenes that cannot be reassigned (substantially final)
For Java engineers starting Kotlin from now on
Why Java String typeclass comparison (==) cannot be used
Check with Java / Kotlin that files cannot be written in UAC on Windows
Kotlin's reified function cannot be called from java.
Please note that Spring Boot + Tomcat 8.5.8 cannot be used!
Problems that can easily be mistaken for Java and JavaScript
Tools and commands that may be useful for Java troubleshooting
Because getSupportLoaderManager cannot be used
Books used for learning Java
Java Stream cannot be reused.
Static analysis tool that can be used on GitHub [Java version]
Summary of ORM "uroboroSQL" that can be used in enterprise Java
I made a question that can be used for a technical interview
[Java] Protected methods cannot always be called from within a subclass