Sécurité des threads
Si votre code est multi-thread, il est alors possible. Par exemple:
public class C {
private Hashtable agents = new Hashtable();
public iterate() {
if(agents != null) {
for (Iterator iter = agents.keySet().iterator(); iter.hasNext();) {
// Code goes here
}
}
}
Si un autre thread met à agents
null
immédiatement après la déclaration exécute if
(mais avant la boucle for
), alors vous obtiendrez un NullPointerException
. Évitez cela en utilisant des accesseurs (combinés avec une initialisation paresseuse).
Aussi, comme d'autres l'ont mentionné, évitez de telles constructions en boucle en faveur de génériques, si possible. Voir d'autres réponses pour plus de détails.
accesseurs offrent une protection
Si vous utilisez toujours le schéma suivant, vous aurez jamais NullPointerException
s dans votre code source (code tiers, d'autre part, pourrait avoir des problèmes qui causent votre code à l'échec indirectement, ce qui ne peut être facilement évité).
public class C {
private Hashtable agents;
private synchronized Hashtable getAgents() {
if(this.agents == null) {
this.agents = new Hashtable();
}
return this.agents;
}
public iterate() {
Hashtable agents = getAgents();
for (Iterator iter = agents.keySet().iterator(); iter.hasNext();) {
// Code goes here
}
}
}
Le code qui itère sur les agents n'a plus besoin de vérifier null
. Ce code est beaucoup plus robost pour plusieurs raisons. Vous pouvez remplacer Hashmap
(ou tout autre type de données abstrait, tel que ConcurrentHashMap<K,V>
) pour Hashtable
.
ouvert-fermé Principe
Si vous sentez particulièrement généreux avec votre temps, vous pouvez aller aussi loin que:
public class C {
private Hashtable agents;
private synchronized Hashtable getAgents() {
if(this.agents == null) {
this.agents = createAgents();
}
return this.agents;
}
public iterate() {
Iterator i = getAgentKeyIterator();
while(i.hasNext()) {
// Code that uses i.next() ...
}
}
protected Hashtable createAgents() {
return new Hashtable();
}
private Iterator getAgentKeyIterator() {
return getAgentKeys().iterator();
}
private KeySet getAgentKeys() {
return getAgents().keySet();
}
}
Cela permettrait à des sous-classes (écrit par d'autres développeurs) de se substituer à propre sous-classe du type de données abstrait utilisé (permettant au système une plus grande flexibilité en accord avec le Open-Closed Principle), sans avoir à modifier (ou copier/perdre) votre travail original.
Ehm, qu'est-ce que NPE? –
@Bart van Heukelom: 'NullPointerException' – Powerlord