2017-06-30 1 views
0

Disons que j'ai un Map<Key,Closeable> et si une clé est retirée de la carte, je veux fermer le Closeable. Normalement, j'ai quelque chose commeutiliser try-with-resources pour fermer un Closeable

Closeable c = map.remove(key); 
c.close(); 

Mon Eclipse me met en garde contre « c» des ressources devrait être géré par essayer avec des ressources », donc est-il mieux juste d'écrire ce qui suit?

try(Closeable c = map.remove(key)) {} 

Dans ma mise en œuvre spéciale j'ai une sous-classe de Closeable, où close() ne jette pas un IOException, donc pas la gestion des exceptions est nécessaire.

+0

il appelle automatiquement 'c.close()' après le bloc 'try' – Jerry06

+1

Il est bon d'utiliser l'instruction' try-with-resources', alors quelle est votre question? –

+0

Pouvez-vous donner plus de détails sur les objets pouvant être fermés, pourquoi ils sont placés dans une carte et pourquoi doivent-ils être fermés lorsqu'ils sont retirés de cette carte? – WilQu

Répondre

1

Le point d'essayer avec-ressources est que:

  • L'ouverture de la ressource Closeable est fait dans l'instruction try
  • L'utilisation de la ressource se trouve dans le bloc de l'instruction try
  • close() est appelée automatiquement pour vous.

donc votre code suggéré:

try(Closeable c = map.remove(key)) {} 

... ne satisfait pas au point d'essayer avec des ressources, puisque vous n'êtes pas utiliser la ressource à l'intérieur du bloc. Votre Closeable est probablement déjà ouvert avant cette déclaration.

Je suppose que vous avez du code grâce auquel un tas de ressources est ouvert, le travail est fait, puis elles sont toutes fermées en travaillant à travers la carte.

C'est OK, et parfois inévitable. Mais il est plus propre, si possible, d'avoir open() et close() dans la même méthode, avec le close() dans un bloc finally, de sorte que vous pouvez voir en un coup d'oeil que chaque open() a un close() correspondant et vous pouvez être sûr que le close() est toujours appelé.

MyCloseable c = MyCloseable.open(...); 
try{ 
     // do stuff with c; 
} finally { 
    try { 
     c.close(); 
    } catch (IOException e) { 
     // ... 
    } 
} 

Une fois que vous avez atteint, essayez avec-ressources rend les choses plus propre:

try(MyCloseable c = MyCloseable.open(...)) { 
    // do stuff with c; 
} 

Si vos exigences signifient que vous ne pouvez pas obtenir ouvrir et fermer dans les mêmes méthodes, puis juste s'en tenir à un close() explicite et ignorer l'avertissement.

+0

Théorique les ressources peuvent être ouvertes pour toujours car il s'agit d'une communication client-serveur et le client peut être connecté pour toujours s'il n'y a pas de délai. – Madjosz

2

Je voudrais simplement ignorer cet avertissement, Si vous gérez la fermeture par vous-même, alors appelez simplement close(). Essayez-avec-ressource vide semble étrange.

Tenir compte à agrandir la carte si étroite sera réalisée automatiquement supprimer:

public class CloseableMap<K,V extends Closeable> extends HashMap<K,V> { 

    @Override 
    public R remove(K key) { 
     V resource = super.remove(key); 
     if (resource != null) { 
      resource.close(); 
     } 
     return resource; 
    } 
}