[JAVA] Road to REPL (?) Création (3)

introduction

REPL réalisé avec Java8, c'est le troisième. Comme l'article précédent pèse plus que prévu, nous allons cette fois créer un objet plus léger.

Interface finalisable

Après avoir utilisé Java pour la première fois depuis longtemps, la première chose qui m'a surpris a été l'absence de destructeur. Lorsque je veux implémenter le soi-disant ** RAII (l'acquisition de ressources est l'initialisation) **, comment puis-je l'implémenter sans destructeur? est devenu. Par conséquent, cette fois, nous allons créer une classe pour réaliser l'acquisition / libération de ressources à utiliser dans REPL et autres.

Comment implémenter RAII en Java

Je ne sais pas très bien comment implémenter la libération des ressources en Java, je vais donc le résumer en gros.

Object.finalize () obsolète

Object.finalize()En remplaçant la méthode, vous pouvez écrire un traitement de publication arbitraire au moment de la récupération de place.


 Cependant, la méthode finalize () est exécutée lorsque l'objet est détruit par le garbage collector, nous ne savons donc pas quand il sera exécuté. Surtout dans l'environnement PC actuel où la mémoire est abondante, elle peut ne pas être appelée tant que l'application n'est pas fermée.
 Pour les ressources qui ne peuvent être utilisées que dans l'application et ne peuvent être réutilisées qu'après le processus de publication (je ne pouvais pas penser à un exemple), il n'y a aucune garantie que le processus de publication fonctionnera avant la réutilisation, utilisez cette méthode. ne peux pas.

 AutoCloseable.close()
 En créant une classe d'implémentation d'interface AutoCloseable et en utilisant le bloc try-with-resource, la méthode close () implémentée est automatiquement appelée à la fin du bloc try.
 Ce format est généralement recommandé, mais il doit être utilisé dans une seule méthode, il ne peut donc pas être utilisé, par exemple, si vous souhaitez détruire un objet de composition lorsque l'objet parent est détruit. Il existe également un moyen d'appeler close () de l'objet de composition par vous-même, mais est-ce l'utilisation d'origine? Je doute si demandé.


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

try ( InputStreamReader in = new InputStreamReader(filepath) ) {
    char c = in.read();  //Traitement utilisant dans
    method(in);   //Il est possible de passer via la méthode en chemin
    // ..Autre traitement
}   //Où est automatiquement libéré

Finalizer (celui que j'expliquerai cette fois)

Par conséquent, nous allons implémenter la classe Finalizer qui libère les objets enregistrés.

Interface finalisable

C'est une interface à implémenter dans la classe dont vous souhaitez terminer le traitement. C'est un mécanisme qui oblige Finlizer à contenir une collection de Finalizable et appelle cleanup () des objets de la collection séquentiellement à la fin.

Interface.java


package console;

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

Classe de finaliseur

Il s'agit du conteneur de la classe d'implémentation Finalizable et de la classe de contrat de traitement de résiliation.

python


package console;

final class Finalizer {
    /**Enregistrement de classe d'implémentation finalisable. */
    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);
    }

    /**Enregistré Finalisable.cleanup()Pour appeler et supprimer dans l'ordre inverse de l'inscription. */
    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<>();
}

Exemple d'enregistrement d'objets dépendants

Si vous souhaitez libérer des ressources et que Hoge est nécessaire pour initialiser Foo, enregistrez-le dans Finlaizer dans l'ordre Hoge → Foo. En faisant cela, Hoge ne sera pas publié avant Foo, donc même si vous utilisez Foo dans Hoge.cleanup (), il n'y aura pas de problème. Cependant, sauf si vous appelez manuellement Foo.cleanup () ...

【Exemple d'utilisation】


    Finalizer fin = new Finalizer();
    Hoge h = new Hoge();
    fin.register(h);
    Foo  f = new Foo(h);
    fin.register(f);
 
    // ... Hoge,Traitement à l'aide de Foo

    fin.cleanup()

Résumé

Finalizer.cleanup () doit être appelé par lui-même lors de la destruction d'un objet, mais si vous l'enregistrez ici, il libèrera les ressources d'un seul coup, donc si vous l'implémentez correctement, vous pouvez résoudre considérablement le problème des fuites de ressources. pense. La méthode cleanup () portant le même nom que la méthode de la classe Finalizer est enregistrée en tant que classe abstraite dans la partie 1 de la classe BaseREPL. Lorsque vous utilisez Finalizer dans une classe dérivée, vous pouvez appeler la méthode Finalizer.cleanup () à partir de cette méthode pour vous assurer que le processus de libération des ressources enregistré juste avant la fin de la méthode BaseREPL.run () est exécuté. Je vais.

Exemple d'implémentation dans REPL


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

    protected void cleanup() {
        finalizer.cleanup(): //nettoyage dans l'ordre obj2, obj1()Est appelé
    }

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

Recommended Posts

Road to REPL (?) Création (3)
Road to REPL (?) Création (1)
Road to REPL (?) Création (2)
19 Correspond à la création d'objet
En route vers l'acquisition de Java SE 11 Silver
La route de JavaScript à Java
à_ ○
La route pour créer un jeu sonore 2
Java SE8 Silver ~ La route à franchir ~
Introduction à kotlin pour les développeurs iOS ⑥ ー création de kotlin
La route pour créer un jeu sonore 3
La route pour créer un jeu sonore 1