Code Java qui ne peut pas être utilisé depuis Kotlin (pour les sessions d'étude en interne)


Code dans lequel j'étais vraiment

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;
    }
}

Bien sûr, l'utilisation d'une telle implémentation Java à partir de Java fonctionne bien.

java


new Desk(Desk.Color.BLUE);

Lorsqu'il est utilisé depuis Kotlin, j'obtiens une erreur de compilation.

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'

Comment éviter

Pour résoudre ce problème (peut-être?), Une méthode statique appelée getColorEnum () a été préparée.

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") //un avertissement de suppression est nécessaire
Desk(Desk.getColorEnum("BLUE")) //J'ai pu mettre une instance Color dans le constructeur Desk

Pourquoi ai-je une erreur / pas?

En regardant quel type de cas provoque une erreur

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 ne semble pas pouvoir accéder à la classe interne statique de la super classe. J'ai jeté un coup d'œil aux spécifications linguistiques sous-jacentes, mais je n'ai pas compris.


Pourquoi pourrait-il être utilisé comme valeur de retour de méthode?

Java semble être capable de définir une classe initialement invisible comme valeur de retour.

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

    private static class InternalBar extends Bar {}
}

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

Vous ne pouvez pas faire ça avec 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()
}

Qu'est-ce que l'avertissement INACCESSIBLE_TYPE?

Le comportement du compilateur Kotlin, qui provoque une erreur lorsqu'il ne peut pas être référencé, ne correspond pas aux spécifications Java décrites ci-dessus et ne peut pas être compilé. Actuellement, il est défini sur Avertissement au lieu d'Erreur de compilation, mais il sera correctement accessible à l'avenir. Il semble qu'il sera à nouveau modifié pour que ce ne soit une erreur de compilation que lorsque ce n'est pas possible.

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


Que faire si getColorEnum () n'est pas fourni du côté de la bibliothèque?

Vous pouvez créer votre propre méthode utilitaire en 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"))

Peut être écrit. Est-ce vraiment la bonne réponse ...?


thanks!

Recommended Posts

Code Java qui ne peut pas être utilisé depuis Kotlin (pour les sessions d'étude en interne)
Nouvelles fonctionnalités de Java 14 pouvant être utilisées pour écrire du code
Notez que les propriétés système, y compris JAXBContext, ne peuvent pas être utilisées dans Java11
Mémo pour la migration de Java vers Kotlin
[Java] Les variables déclarées à l'intérieur de l'instruction `for` ne peuvent pas être utilisées en dehors du bloc` instruction for`
Extrait technologique pouvant être utilisé pour créer des sites EC dans la formation Java
[Java] Scènes qui ne peuvent pas être réaffectées (essentiellement définitives)
Pour les ingénieurs Java qui démarrent Kotlin à partir de maintenant
Pourquoi la comparaison de classe de type chaîne Java (==) ne peut pas être utilisée
Vérifiez avec Java / Kotlin que les fichiers ne peuvent pas être écrits en UAC sous Windows
La fonction modifiée de kotlin ne peut pas être appelée depuis java.
Veuillez noter que Spring Boot + Tomcat 8.5.8 ne peut pas être utilisé!
Problèmes facilement confondus avec Java et JavaScript
Outils et commandes pouvant être utiles pour le dépannage Java
Parce que getSupportLoaderManager ne peut pas être utilisé
Livres utilisés pour apprendre Java
Java Stream ne peut pas être réutilisé.
Outil d'analyse statique pouvant être utilisé avec GitHub [version Java]
Résumé de l'ORM "uroboroSQL" qui peut être utilisé dans le Java d'entreprise
J'ai posé une question qui peut être utilisée pour des entretiens techniques
[Java] Les méthodes protégées ne peuvent pas toujours être appelées depuis une sous-classe