[JAVA] Weg zur REPL (?) Schöpfung (3)

Einführung

REPL mit Java8 erstellt, ist es das dritte. Da der vorherige Artikel mehr wiegt als erwartet, werden wir dieses Mal ein leichteres Objekt erstellen.

Finalisierbare Schnittstelle

Nachdem ich Java zum ersten Mal seit einiger Zeit wieder verwendet hatte, war das erste, was mich überraschte, das Fehlen eines Destruktors. Wie kann ich das sogenannte ** RAII (Ressourcenerfassung ist Initialisierung) ** implementieren, wenn ich es ohne Destruktor implementieren möchte? ist geworden. Daher werden wir dieses Mal eine Klasse erstellen, um die Ressourcenbeschaffung / -freigabe zu realisieren, die in REPL und anderen verwendet werden soll.

So implementieren Sie RAII in Java

Ich bin nicht sehr vertraut mit der Implementierung der Ressourcenfreigabe in Java, daher fasse ich sie grob zusammen.

Object.finalize () Veraltet

Object.finalize()Durch Überschreiben der Methode können Sie eine beliebige Freigabeverarbeitung zum Zeitpunkt der Speicherbereinigung schreiben.


 Die Methode finalize () wird jedoch ausgeführt, wenn das Objekt vom Garbage Collector zerstört wird, sodass wir nicht wissen, wann es ausgeführt wird. Insbesondere in der aktuellen PC-Umgebung, in der viel Speicher vorhanden ist, wird dieser möglicherweise erst aufgerufen, wenn die Anwendung geschlossen wird.
 Für Ressourcen, die nur in einer Anwendung verwendet und erst nach der Release-Verarbeitung wiederverwendet werden können (ich konnte mir kein Beispiel vorstellen), gibt es keine Garantie dafür, dass der Release-Prozess vor der Wiederverwendung funktioniert. Verwenden Sie diese Methode. kann nicht.

 AutoCloseable.close()
 Durch Erstellen einer AutoCloseable-Schnittstellenimplementierungsklasse und Verwenden des Try-with-Resource-Blocks wird die implementierte close () -Methode am Ende des try-Blocks automatisch aufgerufen.
 Dieses Format wird im Allgemeinen empfohlen, muss jedoch innerhalb einer einzelnen Methode verwendet werden, sodass es beispielsweise nicht verwendet werden kann, wenn Sie ein Kompositionsobjekt zerstören möchten, wenn das übergeordnete Objekt zerstört wird. Es gibt auch eine Möglichkeit, close () des Kompositionsobjekts selbst aufzurufen, aber ist es die ursprüngliche Verwendung? Ich bezweifle, wenn ich gefragt werde.


#### **`python`**
```java

try ( InputStreamReader in = new InputStreamReader(filepath) ) {
    char c = in.read();  //Verarbeitung mit in
    method(in);   //Es ist in Ordnung, unterwegs über die Methode zu übergeben
    // ..Andere Verarbeitung
}   //Wobei in automatisch freigegeben wird

Finalizer (der, den ich diesmal erklären werde)

Daher werden wir die Finalizer-Klasse implementieren, die die registrierten Objekte freigibt.

Finalisierbare Schnittstelle

Es ist eine Schnittstelle, die in der Klasse implementiert werden soll, deren Verarbeitung Sie beenden möchten. Es ist ein Mechanismus, der Finlizer veranlasst, eine Sammlung von Finalizable zu speichern und am Ende nacheinander cleanup () der Objekte in der Sammlung aufzurufen.

Interface.java


package console;

interface Interface {
    interface Finalizable {
        void cleanup();
    }
}

Finalizer-Klasse

Dies ist der Container der Finalizable-Implementierungsklasse und der Vertragsklasse für die Terminierungsverarbeitung.

python


package console;

final class Finalizer {
    /**Finalisierbare Registrierung der Implementierungsklasse. */
    final void  register(Interface.Finalizable f) {
        if ( finalizers_.contains(f) ) { return; }
        finalizers_.add(0, f);  // push front
    }

    final void remove(Interface.Finalizable f) {
        if ( !finalizers_.contains(f) ) { return; }
        finalizers_.remove(f);
    }

    /**Registriert Finalisierbar.cleanup()Aufrufen und Löschen in umgekehrter Reihenfolge der Registrierung. */
    final void cleanup() {
        for ( Interface.Finalizable f: finalizers_ ) {
            try {
                f.cleanup();
            } catch(java.lang.RuntimeException e) {
                System.err.println( e.getMessage() );
            }
        }
        finalizers_.clear();
        finalizers_ = null;
    }

    private java.util.List<Interface.Finalizable> finalizers_ = new java.util.ArrayList<>();
}

Beispiel für die Registrierung abhängiger Objekte

Wenn Sie Ressourcen freigeben möchten und Hoge zum Initialisieren von Foo erforderlich ist, registrieren Sie es in Finlaizer in der Reihenfolge Hoge → Foo. Auf diese Weise wird Hoge nicht vor Foo veröffentlicht. Selbst wenn Sie Foo in Hoge.cleanup () verwenden, gibt es kein Problem. Es sei denn, Sie rufen Foo.cleanup () manuell auf ...

【Anwendungsbeispiel】


    Finalizer fin = new Finalizer();
    Hoge h = new Hoge();
    fin.register(h);
    Foo  f = new Foo(h);
    fin.register(f);
 
    // ... Hoge,Verarbeitung mit Foo

    fin.cleanup()

Zusammenfassung

Finalizer.cleanup () muss beim Zerstören eines Objekts von selbst aufgerufen werden. Wenn Sie es jedoch hier registrieren, werden Ressourcen auf einmal freigegeben. Wenn Sie es also ordnungsgemäß implementieren, können Sie das Problem des Ressourcenverlusts erheblich lösen. Überlegen. Die cleanup () -Methode mit demselben Namen wie die Methode in der Finalizer-Klasse wird in Teil 1 der BaseREPL-Klasse als abstrakte Klasse registriert. Wenn Sie Finalizer in einer abgeleiteten Klasse verwenden, können Sie die Finalizer.cleanup () -Methode von dieser Methode aus aufrufen, um sicherzustellen, dass der Ressourcenfreigabeprozess unmittelbar vor dem Ende der BaseREPL.run () -Methode registriert wird. Ich werde.

Implementierungsbeispiel in REPL


class XxxxREPL extends BaseREPL {
    XxxxREPL(String encoding) {
        super(encoding);
        obj1 = new Object1();
        finalizer.register(obj1);
        finalizer.register(obj2);
    }

    protected void cleanup() {
        finalizer.cleanup(): //Bereinigung in der Reihenfolge von obj2, obj1()Wird genannt
    }

    private Finalizer finalizer = new Finalizer();
    private Object1 /* implements Finalizable */  obj1;
    private Object2 /* implements Finalizable */  obj2 = new Object2();
}

Recommended Posts

Weg zur REPL (?) Schöpfung (3)
Weg zur REPL (?) Schöpfung (1)
Weg zur REPL (?) Schöpfung (2)
19 Entspricht der Objekterstellung
Straße nach Java SE 11 Silberakquisition
Der Weg von JavaScript nach Java
to_ ○
Der Weg zur Erstellung eines Soundspiels 2
Java SE8 Silber ~ Der Weg zum Pass ~
Einführung in Kotlin für iOS-Entwickler lin ー Kotlin-Erstellung
Der Weg zur Erstellung eines Soundspiels 3
Der Weg zur Erstellung eines Soundspiels 1