Was mir bei der Verwendung der Schnittstelle einer Funktion mit Standardargumenten in Kotlin aus Java nicht gefällt

Ich denke, es ist üblich, eine Funktion mit Standardargumenten in Kotlin zu definieren und zu verwenden, aber als ich versuchte, sie von Java aus zu verwenden, fühlte ich mich etwas unangenehm. Ich würde gerne wissen, wie es am besten geht, aber ich konnte es nicht finden, also lasse ich es in der Hoffnung, dass es mir jemand sagt.

Beachten Sie, dass der Implementierungsinhalt der Schnittstelle angemessen ist, da es sich um Bestätigungscodes handelt.

Definieren Sie die Verbindungsfunktion, die die Verbindung zur Datenbank mit einem Kreditmuster verwaltet.

ConnectionManager


interface ConnectionManager {

  fun createConnection(host: String): Connection {
    return Connection(host)
  }
  
  fun<A> connect(c: Connection = createConnection("localhost"), f: (Connection) -> A): A {
    try {
      c.begin()
      return f(c)
    } catch (e: Exception) {
      c.rollback()
      throw e
    } finally {
      c.commit()
    }
  }
}

Image, das eine Verbindung zur Datenbank herstellt, eine select-Anweisung ausgibt und eine Benutzerinstanz zurückgibt

UserDao


class UserDao : ConnectionManager {
  fun findById(id: Int): User {
    return connect { c -> c.select("select * from user where id = ${id}", User()) }
  }
}

Bisher gibt es kein besonderes Problem. Ich hatte also ein Problem, als ich diese Schnittstelle auch von Java aus verwenden wollte.

UserDaoJava


public class UserDaoJava implements ConnectionManager {
  public User findById(int id) {
    return connect(c -> c.select("select * from user where id = " + id, new User()) );
  }
}

Dies führt zu einem Kompilierungsfehler. In Java können Argumente, bei denen die Standardargumente weggelassen werden, nicht als eine Verbindungsfunktion aufgerufen werden.

Ich konnte nicht anders, also habe ich der Schnittstelle eine Funktion mit einem Argument hinzugefügt.

ConnectionManager


interface ConnectionManager {

···Kürzung···
  
  //Fügen Sie diese Funktion unvermeidlich hinzu
  fun<A> connect(f: (Connection) -> A): A {
    return connect(createConnection("localhost"), f)
  }
}

Ich frage mich, ob das in Ordnung ist, aber es wird immer noch nicht kompiliert. Unter Java kann die Standardimplementierung der Kotlin-Schnittstelle nicht unverändert aufgerufen werden. Daher muss es auf der Java-Klassenseite überschrieben werden, um verwendet zu werden.

UserDaoJava


public class UserDaoJava implements ConnectionManager {

···Kürzung···
  
  //Ich brauche die unteren drei
  @NotNull
  @Override
  public Connection createConnection(@NotNull String host) {
    //Ich möchte die interne Implementierung von ConnectionManager verwenden, also nenne ich es so wie es ist.
    return ConnectionManager.DefaultImpls.createConnection(this, host);
  }

  @Override
  public <A> A connect(@NotNull Connection c, @NotNull Function1<? super Connection, ? extends A> f) {
    return ConnectionManager.DefaultImpls.connect(this, c, f);
  }

  @Override
  public <A> A connect(@NotNull Function1<? super Connection, ? extends A> f) {
    return ConnectionManager.DefaultImpls.connect(this, f);
  }
}

Jetzt funktioniert auch die Zusammenstellung. Ich mag es jedoch nicht, zwei Verbindungsfunktionen zu sehen, wenn ich ConnectionManager auf der Kotlin-Seite verwende, und vor allem kann ich es nicht jedes Mal überschreiben, wenn ich es auf der Java-Seite verwende.

Erstellen wir also einen Verbindungsmanager für Java!

Löschen Sie zunächst die Verbindungsfunktion mit einem Argument, das zuvor in ConnectionManager hinzugefügt wurde. Definieren Sie dann die Verbindungsfunktion mit einem Argument im neu erstellten Verbindungsmanager für Java.

ConnectionManagerJava


public interface ConnectionManagerJava extends ConnectionManager {
  @NotNull
  @Override
  default Connection createConnection(@NotNull String host) {
    return ConnectionManager.DefaultImpls.createConnection(this, host);
  }

  @Override
  default <A> A connect(@NotNull Connection c, @NotNull Function1<? super Connection, ? extends A> f) {
    return ConnectionManager.DefaultImpls.connect(this, c, f);
  }

  default <A> A connect(@NotNull Function1<? super Connection, ? extends A> f) {
    return connect(createConnection("localhost"), f);
  }
}

Und UserDaoJava wurde geändert, um ConnectionManagerJava zu verwenden

UserDaoJava


public class UserDaoJava implements ConnectionManagerJava {
  public User findById(int id) {
    return connect(c -> c.select("select * from user where id = " + id, new User()) );
  }
}

Damit kann die Verbindungsfunktion mit einem Argument, das Kotlins ConnectionManager hinzugefügt wurde, gelöscht werden, und die Java-Seite ist ebenfalls ordentlich. Da jedoch die Standardimplementierung in der Schnittstelle verwendet wird, besteht das Problem, dass es sich um Java 8 handeln muss.

Mit diesem Gefühl kam ich auf den Trick, eine Schnittstelle auf der Java-Seite zu erstellen, um die Schnittstelle mit Kotlins Standardargumenten aus Java zu verwenden, aber ich habe das Gefühl, dass etwas nicht stimmt. .. ..

Ich frage mich, ob dies die richtige Antwort ist, ob sie sich von der in Kotlins Benutzeroberfläche implementierten unterscheidet oder ob es einen anderen Weg gibt.

Recommended Posts

Was mir bei der Verwendung der Schnittstelle einer Funktion mit Standardargumenten in Kotlin aus Java nicht gefällt
Was ich beim Erstellen eines Servers in Java gelernt habe
Ich möchte eine Funktion mit Kotlin und Java erstellen!
Implementierung einer ähnlichen Funktion in Java
[Anmerkung] Was ich in einem halben Jahr von unerfahrenen (Java) gelernt habe
[Anmerkung] Was ich in einem halben Jahr von unerfahrenen (Java) gelernt habe (1)
[Anmerkung] Was ich in einem halben Jahr von unerfahrenen (Java) gelernt habe (3)
Woran ich dachte, als ich anfing, von Java nach Kotlin zu migrieren
Verwendung der in Kotlins Schnittstelle implementierten Funktion, die in Maven als Standardimplementierung von Java 8 eingeführt wurde
Eine Notiz von dem, worauf ich gestoßen bin und was ich beim Aufholen von Laravel von Rails bemerkt habe
[Rails] Was ich aus einem kleinen Stolperstein bei der Verwendung von Vorfahren gelernt habe
Ich habe eine Lambda-Funktion in Java geschrieben und mit SAM bereitgestellt
Zusammenfassung der Punkte, über die ich mir bei der Migration von Java nach Kotlin Sorgen gemacht habe
Was ich getan habe, als ich Java zu Kotlin konvertiert habe
Rufen Sie eine Methode mit Kotlins Rückrufblock von Java aus auf
Ich habe versucht, eine Anmeldefunktion mit Java zu erstellen
Zusammenfassung der Implementierung von Standardargumenten in Java
Zusammenfassung der Punkte, die Java-Programmierer beim ersten Lesen der Kotlin-Quelle als rutschig empfinden
Ich möchte eine Liste mit Kotlin und Java erstellen!
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben
Ich habe einen RESAS-API-Client in Java erstellt
Ich habe einen C-Parser (wie) mit PEG in Ruby geschrieben
Finden Sie mit Kotlin die Anzahl der Tage in einem Monat
[Rails] Implementierung einer mehrschichtigen Kategoriefunktion unter Verwendung der Abstammung "Ich habe versucht, ein Fenster mit Bootstrap 3 zu erstellen"
Als ich mir Sorgen über statische Methoden in der Java-Oberfläche machte, kam ich zur Reihenfolge der Namensinterpretation
[Java] Vorsichtsmaßnahmen beim Erstellen eines Prozesses, der eine Methode der Abstract-Klasse mit DI aus einer untergeordneten Klasse aufruft
Wenn ich ein Gem mit C-Erweiterung in Ruby installiere, möchte ich es schnell mit mehreren CPU-Kernen wie make -j4 fertigstellen
Ich habe mit JD-Core eine Befehlszeilenschnittstelle mit dem WinMerge Plugin erstellt
Beispiel für die Verwendung der Bulk-API von Salesforce vom Java-Client mit PK-Chunking
Ich habe versucht, die Ajax-Verarbeitung der ähnlichen Funktion in Rails zu implementieren
Ich kann in IntelliJ keine Java-Klasse mit einem bestimmten Namen erstellen
Lassen Sie uns eine TODO-App in Java 6 erstellen. Implementierung der Suchfunktion
Über das, was ich beim Erstellen einer CLJ-Datei mit Clojure getan habe
Lassen Sie uns eine TODO-App in Java 8 erstellen. Implementierung von Bearbeitungsfunktionen
Ich habe eine Sterling-Sorte geschrieben, die sich wie in Java anfühlt
Was ich aus Java gelernt habe, funktioniert mit Visual Studio Code
Was ich oft mache, wenn ich Probleme beim Benennen mit Java habe (etc.)
Ich habe ein PDF mit Java erstellt.
Was ich mit Java Gold gelernt habe
Ich habe versucht, JWT in Java zu verwenden
Was ich mit Java Silver gelernt habe
Ich habe versucht, Google HttpClient von Java zu verwenden
Die Geschichte eines Game Launcher mit automatischer Ladefunktion [Java]
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben (PowerMockito Edition)
Ich habe versucht, mit AI "A3RT" eine Talk-App in Java zu erstellen.
Ich möchte für jedes Array mit Lambda-Ausdruck in Java
[Java] Holen Sie sich MimeType aus dem Inhalt der Datei mit Apathce Tika [Kotlin]
Beim Ausführen einer Funktion in PostgreSQL mit dem Parameter OUT von MyBatis auf CURSOR ist ein Fehler aufgetreten.