net.jcip.annotations.Immutable
.
]]>
edu.umd.cs.findbugs.annotations.NoteSuppressWarnings
.
]]>
@NonNull
sur les méthodes, champs et paramètres. Ceci pourra être utilisé par le détecteur FindNullDeref pour générer des alarmes quand une valeur pouvant être à null
est utilisée dans un contexte où seules des valeurs différentes de null
devraient être utilisées.
]]>
null
sont transmises à ces méthodes.
C'est un détecteur lent
]]>this.getClass().getResource(...)
, qui peuvent donner des résultats inattendus si la classe est étendue par une classe d'un autre paquetage.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>C'est un détecteur modérément rapide.
]]>doPrivileged
.
]]>
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>|
et &
au lieu de ||
et &&
).
]]>
try-catch
qui interceptent une IllegalMonitorStateException
.
]]>
float
).
C'est un détecteur modérément rapide.
]]>Cloneable
.
C'est un détecteur rapide.
]]>Comparator
.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>null
.
]]>
substring(0)
).
]]>
String
.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>finalize()
et autres méthodes liées aux finaliseurs.
C'est un détecteur rapide.
]]>hashCode()
et equals()
.
C'est un détecteur rapide.
]]>notify()
qui ne semblent pas changer l'état d'un objet modifiable.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>Thread.run()
.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>wait()
avec deux (ou plus) verrous en suspens.
C'est un détecteur lent.
]]>wait()
qui ne sont pas dans une condition ou une boucle.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>getXXX
et setXXX
dont le getXXX
n'est pas synchronisé alors que le setXXX
l'est.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>Iterator
.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>String
utilisant les opérateurs ==
ou !=
.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>InputStream.read()
ou InputStream.skip()
qui ignorent la valeur renvoyée.
C'est un détecteur rapide.
]]>Serializable
.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>wait()
qui ne sont pas dans une boucle.
C'est un détecteur rapide.
]]>NullPointerException
pourrait être déclenchée. Il recherche également les comparaisons redondantes de références avec null
.
C'est un détecteur lent.
]]>C'est un détecteur lent.
]]>null
. Renvoyer un tableau de longueur nulle est généralement préférable dans ce cas au renvoi d'une référence à null
.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>java.util.concurrent
) qui sont acquis mais non libérés dans tous les chemins d'exécution possible d'une méthode.
C'est un détecteur modérément rapide.
Notez que pour utiliser ce détecteur vous devez avoir le paquetage java.util.concurrent
dans le classpath (ou être en train d'analyser le paquetage lui-même).
==
ou !=
, et que la classe est d'un type (java.lang.String
par exemple) tel que comparer les valeurs par références est généralement une erreur.
C'est un détecteur lent.
]]>wait()
, notify()
ou notifyAll()
qui ne semblent pas être effectués sur un objet verrouillé.
C'est un détecteur modérément rapide.
Ce détecteur est désactivé parce qu'il est toujours en cours de développement et produit trop de fausses alarmes.
]]>C'est un détecteur lent.
]]>C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>C'est un détecteur modérément rapide.
]]>C'est un détecteur modérément rapide.
]]>C'est un détecteur rapide.
]]>String
utilisant +
.
C'est un détecteur rapide.
]]>Collections
en tableaux en passant un tableau de longueur nulle à la méthode toArray()
.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>Adapter
et surcharge une méthode Listener
avec une signature erronée.
C'est un détecteur rapide.
]]>getXXX
ou setXXX
d'un ResultSet
avec un champ index à 0. Les indexes des champs ResultSet
commençant à 1, c'est toujours une erreur.
C'est un détecteur rapide.
]]>instanceof
alors qu'une détermination statique serait possible.
C'est un détecteur rapide.
]]>init()
. Ces appels feraient échouer le constructeur.
C'est un détecteur rapide.
]]>equals(java.lang.Object)
sur des tableaux ou des classes finales qui ne surchargent pas la méthode equals
de la classe Object
. Cela signifie que la sémantique de equals est la même que ==
, ce qui est probablement une erreur.
]]>
Thread.interrupted()
à partir d'un contexte non statique. Si l'appel provient de Thread.currentThread().interrupted()
, l'exercice est inutile et il suffit d'utiliser Thread.interrupted()
. Si l'appel provient d'un objet thread quelconque, c'est probablement une erreur puisque interrupted()
est toujours appelé sur le thread en cours.
]]>
C'est un détecteur moyennement rapide.
]]>C'est un détecteur rapide.
]]>Map
en utilisant une clé récupérée à partir d'un itérateur sur keySet
.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>catch
qui interceptent Exception
, alors qu'aucun code dans le bloc ne déclenche Exception
.
]]>
C'est un détecteur rapide.
]]>C'est un détecteur lent.
]]>java.lang.Math
sur des valeurs constantes, dont le résultat est connu et constant. Il est plus rapide et parfois plus précis d'utiliser le résultat constant à la place.
]]>
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>wait()
, notify()
ou notifyAll()
avec la référence this
. Ceci expose l'implémentation de la synchronisation comme un artefact
public de la classe. Les objets utilisant une instance de cette classe pourraient l'utiliser également comme leur propre objet de synchronisation et provoquer des ravages dans l'implémentation de base.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>Serializable
dans des sessions Http.
]]>
Serializable
transmis à la méthode writeObject
d'un ObjectOutput
.
]]>
Thread.sleep()
effectué alors que le verrou est tenu.
C'est un détecteur lent.
]]>if/else
ou switch
qui possèdent le même code pour leurs deux branches, rendant le test inutile. Ceci arraive souvent suite à un copier/coller entre les branches, entraînant une logique incorrecte pour l'une des branches.
C'est un détecteur rapide.
]]>protected
permettrait une écriture directe dans le champ.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>equals(Object)
qui déréférence leur paramètre de façon inconditionnelle. Ceci contredit le contrat défini dans java.lang.Object.equals()
, qui stipule que dans le cas d'un paramètre à null
la méthode doit renvoyer false
.
C'est un détecteur lent.
]]>C'est un détecteur rapide.
]]>public
ou private
pour représenter le véritable objectif du champ. Ceci est probablement causé par une modification dans le mode d'utilisation de la classe qui n'a pas été complétement pris en compte.
C'est un détecteur rapide.
]]>C'est un détecteur rapide.
]]>TrainNullReturnValues
établit la liste des méthodes qui peuvent renvoyer null
et la stocke dans un fichier. Le fichier produit est disponible pour d'autres passes d'analyse afin d'amméliorer la précision des détecteurs de déréférencement de null
. Cette analyse préalable ne renvoie aucune alarme.
C'est un détecteur lent.
]]>TrainUnconditionalParamDerefs
établit la liste des méthodes qui déréférencent leurs paramètres de façon inconditionnelle et la sauvegarde dans un fichier. Le fichier produit est disponible par la suite pour permettre d'augementer la précision des détecteurs de déréférencement de null
. Cette analyse préalable ne renvoie aucune alarme.
C'est un détecteur lent.
]]>TrainFieldStoreTypes
établit la liste des types stockés dans les champs et la sauvegarde dans un fichier. Le fichier produit est disponible par la suite pour rendre les analyses de types plus précises.
C'est un détecteur lent.
]]>TrainNonNullAnnotations
établit la liste des annotations @NonNull
et @PossiblyNull
et la sauvegarde dans un fichier.
C'est un détecteur rapide.
]]>Ne l'activez pas.
]]>show()
, setVisible()
et pack()
créent les ressources associées à la fenêtre. En même temps que la création de ces ressources, le système crée le processus Swing de répartition de évènements.
Ceci pose problème car le processus de répartition des évènements peut notifier des écouteurs alors que pack()
et validate()
sont toujours en cours de traitement. Cette situation peut conduire à ce que deux processus essayent d'accèder en même temps au composant, ce qui est une faille sérieuse qui peut provoquer des interblocages et autres problèmes de synchronisation.
Un appel à pack()
provoque l'initialisation du composant. Quand ils s'initialisent (sans être forcément visibles), les composants peuvent émettre des évènements vers le processus de répartition des évènements de Swing.
StackOverflowEception
.
]]>
java.util.concurrent
(inclus dans Java 5.0).
]]>
this.getClass().getResource(...)
peut rendre des résultats différents de ceux attendus si la classe est étendue par une classe d'un autre paquetage.
]]>
putNextEntry()
, immédiatement suivi d'un appel à closeEntry()
. Ceci crée une entrée de fichier Zip vide. Le contenu des entrées devrait être écrit dans le fichier Zip entre les appels à putNextEntry()
et closeEntry()
.
]]>
putNextEntry()
, immédiatement suivi d'un appel à closeEntry()
. Ceci crée une entrée de fichier Jar vide. Le contenu des entrées devrait être écrit dans le fichier Jar entre les appels à putNextEntry()
et closeEntry()
.
]]>
IllegalMonitorStateException
n'est généralement déclenchée que dans le cas d'une faille dans la conception du code (appeler wait()
ou notify()
sur un objet dont on ne possède pas le verrou).
]]>
float
). Les float
peuvent être très imprécis. Par exemple, 16777216.0f +1.0f = 16777216.0f. Envisagez d'utiliser la double précision à la place.
]]>
Cloneable
sans définir ou utiliser la méthode clone()
.
]]>
clone()
qui n'appelle pas super.clone()
, et n'est pas finale. Si cette classe ("A") est étendue par une classe fille ("B"), et que la classe fille B appelle super.clone()
, alors il est probable que la méthode clone()
de B retournera un objet de type A, ce qui viole le contrat standard de clone()
.
Si toutes les méthodes clone()
appellent super.clone()
, elles ont alors la garantie d'utiliser Object.clone()
, qui retourne toujours un objet du type correct.
doPrivileged
.
]]>
doPrivileged
au cas ou il serait appelé par du code ne possédant pas les droits requis.
]]>
final
.
]]>
@Retention
différente de la rétention "source uniquement" par défaut, l'annotation n'est pas conservée dans le fichier .class et ne peut pas être utilisée par réflexion (par exemple avec la méthode isAnnotationPresent()
).
]]>
System.exit()
arrête toute la JVM. Cela ne doit être fait que lorsque c'est nécessaire. De tels appels rendent difficile ou impossible l'invocation de votre code par d'autre code. Envisagez de déclencher une RuntimeException
à la place.
]]>
System.runFinalizersOnExit
ou Runtime.runFinalizersOnExit
pour quelque raison que ce soit : elles font partie des méthodes les plus dangeureuses des librairies Java
Joshua Bloch
]]>java.lang.String(String)
gaspille de la mémoire puisque l'objet ainsi construit serait fonctionnellement identique à la chaîne passée en paramètre. Utilisez juste la chaîne en argument directement.
]]>
java.lang.String
en utilisant le constructeur sans argument gaspille de la mémoire parce que l'objet ainsi créé serait fonctionnellement identique à la constante de chaîne vide "". Java garantie que les chaînes constantes identiques seront représentées par le même objet String
. C'est pourquoi vous devriez directement utiliser la constante de chaîne vide.
]]>
String.toString()
est juste une opération redondante. Utilisez directement l'objet String
.
]]>
Dans le passé, les cas où des personnes ont explicitement invoqué le ramasse-miettes dans des méthodes telles que close()
ou finalize()
ont creusés des gouffres dans les performances. Le ramasse-miettes peut-être très coûteux. Toute situation qui force des centaines ou des milliers de ramasse-miettes mettra à genoux une machine.
java.lang.Boolean
gaspille la mémoire puisque les objets Boolean
sont immuables et qu'il n'y a que deux valeurs utiles de ce type. Utilisez à la place la méthode Boolean.valueOf()
pour créer des objets Boolean
.
]]>
String.toUpperCase(Locale l)
ou String.toLowerCase(Locale l)
à la place.
]]>
toString()
. Il est plus efficace de simplement utiliser la forme statique de toString
qui accepte la valeur primitive. Donc,
Remplacer... | Avec... |
---|---|
new Integer(1).toString() | Integer.toString(1) |
new Long(1).toString() | Long.toString(1) |
new Float(1.0).toString() | Float.toString(1.0) |
new Double(1.0).toString() | Double.toString(1.0) |
new Byte(1).toString() | Byte.toString(1) |
new Short(1).toString() | Short.toString(1) |
Boolean.valueOf(true).toString() | Boolean.toString(true) |
getClass()
afin d'obtenir l'objet Class
correspondant. Il est plus simple d'accèder directement à la propriété .class
de la classe.
]]>
wait()
sur un objet java.util.concurrent.locks.Condition
. L'attente d'une Condition
devrait être faite en utilisant l'une des méthodes await()
définies dans l'interface Condition
.
]]>
Random.nextInt(n)
.
]]>
r
est un java.util.Random
, vous pouvez générer un nombre aléatoire entre 0 et n-1 en utilisant r.nextInt(n)
plutôt que (int)(r.nextDouble() * n)
.
]]>
execute
d'une commande SQL (statement) avec une chaîne qui semble générée dynamiquement. Préférer la préparation de la commande avec un PreparedStatement
, c'est plus efficace et bien moins vulnérable aux attaques par injection SQL (insertion de code SQL malveillant au sein d'une requête).
]]>
run
, soit par dérivation de la classe Thread
, soit en transmettant un objet Runnable
. Ce thread ne fait donc rien sauf perdre du temps.
]]>
finalize()
d'une classe devrait avoir un accès protégé, pas public.
]]>
finalize()
vides sont inutiles, donc elles devraient être supprimées.
]]>
finalize()
vide rend explicitement inutile tout finaliseur défini dans les super-classes. Toute action définie dans un finaliseur d'une superclasse sera ignorée. A moins que cela ne soit voulu, supprimer cette méthode.
]]>
finalize()
fait est d'appeler la méthode finalize()
de la super-classe, ce qui la rend redondante. Supprimez la.
]]>
finalize()
n'appelle pas la méthode finalize()
de sa classe mère ; donc toutes les actions définies au niveau de la classe mère seront ignorées. Ajoutez un appel à super.finalize()
.
]]>
finalize()
d'un objet. Les méthodes finalize()
étant sensées n'être appelées qu'une fois, et uniquement par la JVM, c'est une mauvaise idée.
]]>
equals()
, mais appelle la méthode normale equals(Object)
définie dans la classe de base java.lang.Object
. La classe devrait probablement définir une version non covariante de equals()
. (C'est-à-dire une méthode avec la signature boolean equals(java.lang.Object)
.
]]>
equals()
. Pour surcharger correctement la méthode equals()
de java.lang.Object
, le paramètre de equals()
doit être du type java.lang.Object
.
]]>
null
, mais qui est déréférencée sans test de nullité.
]]>
equals(Object)
ne respecte pas le contrat défini par java.lang.Object.equals()
car elle ne vérifie la nullité du paramètre reçu en argument. Toutes les méthodes equals()
doivent renvoyer false
quand elles reçoivent une valeur à null
.
]]>
equals(Object)
contredit le contrat défini dans java.lang.Object.equals()
car elle ne vérifie pas le cas du null
passé en paramètre. Toutes les méthodes equals()
devraient renvoyer false
quand un null
leur est passé.
]]>
compareTo()
. Pour correctement surcharger la méthode compareTo()
de l'interface Comparable
, le paramètre de compareTo()
doit être du type java.lang.Object
.
]]>
hashCode()
mais hérite la méthode equals()
de java.lang.Object
(qui définit l'égalité par comparaison des références des objets). Bien que cela satisfasse certainement le contrat indiquant que les objets égaux doivent avoir des codes de hachage égaux, ce n'est certainement pas ce qui était voulu lors de la surcharge de la méthode hashCode()
(Surcharger hashCode()
implique que l'identité des objets soit basée sur des critères plus compliqués qu'une simple égalités des références.)
Si vous ne pensez pas que des instances de cette classe soient un jour insérées dans des HashMap
/HashTable
, l'implémentation recommendée de hashCode
est :
public int hashCode() { assert false : "hashCode not designed"; return 42; // any arbitrary constant will do }]]>
hashCode()
mais pas de méthode equals()
. C'est pourquoi cette classe peut violer le contrat indiquant que des objets identiques doivent avoir des codes de hachage identiques.
]]>
equals(Object)
, pas hashCode()
, et hérite de l'implémentation de hashCode()
issue de java.lang.Object
(qui renvoie le code de hachage d'identité, une valeur arbitraire assignée à l'objet par la JVM). C'est pourquoi la classe a des chances de violer le contrat impliquant que des objets égaux doivent avoir des codes de hachage identiques.
Si vous ne pensez pas que des instances de cette classe soient un jour insérés dans desHashMap
/Hashtable
, l'implémentation recommendée est du type :
public int hashCode() { assert false : "hashCode not designed"; return 42; // any arbitrary constant will do }]]>
equals((Object)
d'une super-classe abstraite, et de la méthode hashCode()
de l'objet java.lang.Object
(qui renvoi le code de hachage d'identité, une valeur arbitraire assignée à l'objet par la JVM). C'est pourquoi la classe viole probablement le contrat indiquant que des objets égaux doivent avoir des codes de hachage identiques.
Si vous ne souhaitez pas définir une méthode hashCode()
et/ou ne pensez pas que l'objet puisse un jour être mis dans des HashMap
/Hashtable
, définissez une méthode hashCode()
déclenchant une UnsupportedOperationException
.
equals(Object)
, mais pas hashCode()
. C'est pourquoi la classe peut violer le contrat indiquant que des objets égaux doivent avoir des codes de hachage identiques.
]]>
equals()
. Pour surcharger correctement la méthode equals()
de java.lang.Object
, le paramètre de equals()
doit être du type java.lang.Object
.
]]>
java.lang.String
au moyen de l'égalité par référence des opérateurs ==
ou !=
. A moins que les deux chaînes ne soient des constantes dans le fichier source ou aient été internalisées au moyen de la méthode String.intern()
, deux chaînes identiques peuvent être représentées par deux objets String
différents. Envisagez d'utiliser la méthode equals(Object)
à la place.
]]>
compareTo()
. Pour surcharger correctement la méthode compareTo()
de l'interface Comparable
, le paramètre de compareTo()
doit être du type java.lang.Object
.
]]>
net.jcip.annotations.GuardedBy
, mais peut être utilisé d'une façon qui contredit l'annotation.
]]>
Un bogue typique déclenchant ce détecteur est l'oubli de la synchronisation sur l'une des méthodes d'une classe qui essaye d'être sûre vis-à-vis des threads.
Vous pouvez sélectionner les noeuds nommés "Accès non synchronisés" pour avoir la position exacte dans le code où le détecteur pense qu'un champ est accédé sans synchronisation.
Notez qu'il y a diverses sources d'inexactitude dans ce détecteur ; par exemple, le détecteur ne peut pas repérer statiquement toutes les situations dans lesquelles un verrou est obtenu. En fait, même lorsque le détecteur repère effectivement des accès avec et sans verrou, le code concerné peut quand même être correct.
Cette description se réfère à la version "IS2" du détecteur, qui est plus précise pour détecter les accès avec et sans verrous que l'ancien détecteur "IS".
]]>notify()
ou notifyAll()
est effectué sans aucun changement (apparent) de l'état d'un objet modifiable. En général, appeler une méthode notify()
dans un moniteur est effectué parce qu'une condition quelconque attendue par un autre thread est devenue vraie. Dans tous les cas, pour que la condition ait un sens, elle doit porter sur un objet visible des deux threads.
Ce bogue n'indique pas nécessairement une erreur puisque la modification de l'état de l'objet peut avoir eu lieu dans une méthode qui appelle la méthode contenant la notification.
]]>run()
sur un objet. En général, les classes implémentent l'interface Runnable
parce qu'elles vont avoir leur méthode run()
invoquée dans un nouveau thread, auquel cas Thread.start()
est la bonne méthode à appeler.
]]>
wait()
et notify()
).
]]>
&
ou |
) plutôt que les opérateurs booléens (&&
ou ||
). La logique binaire entraîne l'évaluation systématique de toute l'expression, même quand le résultat pourrait être immédiatement déduit. Ceci est moins performant et peut provoquer des erreurs lorsque la partie gauche de l'expression masque des cas de la partie droite.
]]>
wait()
ne libère que le verrou sur l'objet accueillant le wait()
, mais aucun autre verrou. Ce n'est pas obligatoirement un bogue, mais il vaut mieux examiner ça en détails.
]]>
notify()
ou notifyAll()
alors que deux verrous sans en cours. Si cette notification tente de réveiller un wait()
basé sur les mêmes verrous cela peut provoquer un inter-blocage puisque le wait()
ne libérera qu'un des verrous et que le notify()
ne pourra pas récupérer l'autre verrou et échouera. Si il y a aussi une alarme sur un wait()
avec deux verrous, la probabilité d'une erreur est plutôt élevée.
]]>
java.lang.Object.wait()
qui n'est pas protégé par une condition. Si la condition que la méthode essaye d'attendre a déjà été remplie, le thread risque d'attendre indéfiniment.
]]>
getXXX
et setXXX
similaires dont la méthode setXXX
est synchronisée tandis que la méthode getXXX
ne l'est pas. Ceci peut entraîner un comportement incorrect à l'exécution car l'appelant de la méthode getXXX
ne verra pas obligatoirement l'objet dans un état consistant. La méthode getXXX
devrait être synchronisée.
]]>
foo
sera à null
.
public class CircularClassInitialization {
static class InnerClassSingleton extends CircularClassInitialization {
static InnerClassSingleton singleton = new InnerClassSingleton();
}
static CircularClassInitialization foo = InnerClassSingleton.singleton;
}
java.util.Iterator
. Néanmoins, sa méthode next()
n'est pas capable de déclencher java.util.NoSuchElementException
. La méthode next()
devrait être modifiée pour déclencher NoSuchElementException
si elle est appelée alors qu'il n'y a plus d'éléments à renvoyer.
]]>
synchronized() {}
L'utilisation de blocs synchronisés vides est bien plus subtile et dure à réaliser correctement que bien des gens ne le reconnaissent, et de plus ne correspond que rarement à la meilleure des solutions.
]]>Typiquement, oublier de synchroniser une des méthodes dans une classe essayant d'être sûre vis-à-vis des threads est un bogue signalé par ce détecteur.
NB : il y a diverses sources d'inexactitude dans ce détecteur ; par exemple, le détecteur ne peut pas déterminer statiquement toutes les situations dans lesquelles un verrou est détenu. Ainsi, même lorsque le détecteur repère effectivement des accès verrouillés / non verrouillés, le code en question peut tout de même être correct.
]]>Hashtable
et peut-être modifié par accident ou par du code malveillant d'un autre paquetage. Ce code peut librement modifier le contenu de la Hashtable
.
]]>
super
(Ex : appelé super.foo(17)
) ce qui clarifiera votre code pour les autres lecteurs et pour FindBugs.
]]>
hashcode()
. Cette méthode ne surcharge pas la méthode hashCode()
de java.lang.Object
, surchage qui était pourtant sans doute le but visé.
]]>
tostring()
. Cette méthode ne surcharge pas la méthode toString()
de java.lang.Object
, surchage qui était pourtant sans doute le but visé.
]]>
equal(Object)
. Cette méthode ne surcharge pas la méthode equals(Object)
de java.lang.Object
, surchage qui était pourtant sans doute le but visé.
]]>
Exception
alors que son nom se termine par 'Exception'. Ceci risque de porter à confusion les utilisateurs de cette classe.
]]>
java.io.InputStream.read()
qui peut renvoyer de multiples octets. Si la valeur renvoyée n'est pas vérifiée, l'appelant ne sera pas capable de gérer correctement le cas ou moins d'octets que prévu auront été lus. C'est un bogue particulièrement insidieux car dans la plupart des programmes les lectures renvoient effectivement souvent le nombre d'octets demandé, les plantages restant sporadiques.
]]>
java.io.InputStream.skip()
, qui peut sauter de multiples octets. Si la valeur renvoyée n'est pas vérifiée, l'appelant n'est pas capable de gérer correctement les cas ou moins d'octets que prévu auront été sautés. C'est un type de bogue particulièrement insidieux car la plupart du temps le bon nombre d'octet sera effectivement sauté, et les plantages seront sporadiques. Néanmoins, sur les flux bufferisés, skip()
ne s'applique qu'aux données du buffer et échoue fréquemment à sauter le nombre d'octets demandé.
]]>
readResolve
soit prise en compte pas le mécanisme de sérialisation, elle doit avoir Object comme type de retour.
]]>
transient
et n'étant pas alimenté par les méthodes readObject
et readResolve
, il contiendra la valeur par défaut dans toutes les instances désérialisées de la classe.
]]>
Serializable
et défini une méthode pour personnaliser la sérialisation/désérialisation. Mais cette méthode n'étant pas déclarée privée elle sera ignorée silencieusement par les API de sérialisation/désérialisation.
]]>
Externalizable
, mais ne définit pas de constructeur par défaut. Quand les objets Externalizable
sont déserialisés, ils doivent d'abord être construit au moyen du constructeur par défaut. Cette classe n'en ayant pas, sérialisation et désérialisation échoueront à l'exécution.
]]>
Serializable
mais pas sa super-classe. Quand un tel objet est désérialisé, les champs de la classe mère doivent être initialisés en invoquant le constructeur par défaut de la super-classe. Comme la super-classe n'en a pas, sérialisation et désérialisation échoueront à l'exécution.
]]>
Serializable
mais ne définit pas de champ serialVersionUID
. Une modification aussi simple qu'ajouter une référence vers un objet .class
ajoutera des champs synthétiques à la classe, ce qui malheureusement changera la valeur implicite de serialVersionUID
(Ex. : ajouter une référence à String.class
générera un champ statique class$java$lang$String
). De plus, différents compilateurs source vers bytecode peuvent utiliser différentes conventions de nommage pour les variables synthétiques générées pour référencer les objets classes et les classes internes. Afin de garantir l'interopérabilité de Serializable
suivant les versions, pensez à ajouter un champ serialVersionUID
explicite.
]]>
Comparator
. Vous devriez vérifier si elle doit ou pas également implémenter l'interface Serializable
. Si un comparateur est utilisé pour construire une collection triée, telle que TreeMap
, alors le TreeMap
ne sera sérialisable uniquement si le compareteur l'est aussi. Puisque la plupart des comparateurs ont de petits voire aucun états, les rendre sérialisables est généralement une technique de programmation défensive simple et bénéfique.
]]>
switch
dont l'un des cas déborde sur le suivant. Normalement, vous devez terminer chaque cas avec une instruction break
ou return
.
]]>
writeObject()
qui est synchronisée ; mais aucune autre méthode de cette classe n'est synchronisée.
]]>
Serializable
définit une méthode readObject()
qui est synchronisée. Par définition, un objet créé par désérialisation n'est accessible que par un unique thread, donc il n'y a aucun intérêt à synchroniser readObject()
. Si la méthode readObject()
en elle-même rend l'objet visible d'un autre thread, vous avez un exemple de style de code très douteux.
]]>
serialVersionUID
qui n'est pas statique. Le champ devrait être rendu statique si son but est de préciser l'identifiant de version utilisé pour la sérialisation.
]]>
serialVersionUID
qui n'est pas final
. Ce champ devrait être rendu final
si son but est de préciser l'identifiant de version utilisé pour la sérialisation.
]]>
serialVersionUID
qui n'est pas de type long
. Ce champ devrait être de type long
si son but est de préciser l'identifiant de version utilisé pour la sérialisation.
]]>
Serializable
définit un champ d'instance non primitif qui n'est ni transient
, ni Serializable
ou java.lang.Object
, et qui ne semble pas implémenter l'interface Externalizable
ou les méthodes readObject()
et writeObject()
. Les objets de cette classe ne seront pas désérialisés correctement si un objet non Serializable
est stocké dans ce champ.
]]>
transient
d'une classe sérialisable.
]]>
final
qui est initialisé par une valeur statique déterminée à la compilation. Envisagez de rendre ce champ static
.
]]>
null
et donc toutes les lectures de ce champ renverront null
. Vérifiez si c'est une erreur ou alors supprimez ce champ qui est inutile.
]]>
null
suite à une vérification précédente. Bien que cela soit valide, ce peut être une erreur (peut-être vouliez-vous référencer une autre valeur ou le test précédent aurait-il due vérifier non-null plutôt que null).
]]>
readLine()
est immédiatement déréférencé. S'il n'y a plus d'autre lignes de texte à lire, readLine()
retournera null
ce qui provoquera une NullPointerException
lors du déréférencement.
]]>
NullPointerException
.
]]>
static
.
]]>
null
une fois l'initialisation de l'objet terminée. Ce peut être un erreur de code, ou bien la classe contenant le champ est construite de telle manière que le champ est écrit en fonction de l'appel de méthodes dans un certain ordre (un peu délicat mais pas nécessairement mauvais).
]]>
null
une fois l'objet initialisé. Soit il s'agit d'une erreur, soit il s'agit d'un design douteux puisque ce champ génèra une exception s'il est déréférencé avant toute initialisation.
]]>
static
. Puisque les classes anonymes ne peuvent pas être marquées comme static
, il faudrait également nommer cette classe.
]]>
static
. Puisque la référence à l'objet créateur est requise durant la construction de la classe interne, le constructeur de celle-ci devrait-être modifié afin d'accepter en argument cette référence.
]]>
java.lang.Object.wait()
qui n'est pas dans une boucle. Si le moniteur est utilisé pour des conditions multiples, la condition que l'appelant attend peut ne pas être celle qui s'est réellement déclenchée.
]]>
java.util.concurrent.await()
(ou une variante) qui n'est pas dans une boucle. Si cet objet est utilisé pour de multiples conditions, la condition que l'appelant espère réveiller pourra être ou ne pas être celle qui le sera effectivement.
]]>
notify()
plutôt que notifyAll()
. Le moniteur Java est souvent utilisé pour de multiples conditions. Appeler notify()
ne réveille qu'un thread, ce qui signifie que le thread réveillé peut ne pas être celui qui attend la condition que l'appelant vient de remplir.
]]>
String.indexOf()
et vérifie si le résultat est strictement positif ou pas. Il est plus habituel de vérifier si le résultat est négatif. Il n'est strictement positif que lorsque la sous-chaine recherchée apparaît ailleurs qu'au début de la chaine.
]]>
readLine()
est ignorée après avoir vérifié s'il n'est pas à null
. Dans quasiment tous les cas, si le résultat n'est pas à null
, vous souhaiterez utiliser cette valeur. Appeler de nouveau readLine()
vous renverra une ligne différente.
]]>
String dateString = getHeaderField(name); dateString.trim();
Le programmeur semble croire que la méthode trim()
mettra à jour l'objet String
référencé par dateString
. Mais, les objets String
étant constants, la fonction renvoi une nouvelle valeur qui est ici ignorée. Le code devrait être corrigé en :
]]>String dateString = getHeaderField(name); dateString = dateString.trim();
null
est déréférencé ici. Ceci va mener à une NullPointerException
quand le code sera exécuté.
]]>
null
est stockée dans un champ qui a été annoté comme NonNull
.
]]>
null
dans le chemin d'exception est déréférencé ici. Cela va mener à une NullPointerException
quand le code sera exécuté. Notez que puisque FindBugs ne détecte pas les chemins d'exception irréalisables, il est possible que cette alarme soit injustifiée.
Notez aussi que FindBugs considère le choix par défaut d'un switch
comme étant dans le chemin d'exception, puisque ce choix est souvent irréalisable.
null
à l'exécution. Cela peut conduire à une NullPointerException
quand le code est exécuté.
]]>
null
dans un des chemins d'exception est déréférencée ici. Ceci peut conduire à une NullPointerException
à l'exécution du code. Notez que comme FindBugs ne repère pas les chemins d'exception irréalisables, il est possible que cette alarme soit injustifiée.
Notez également que FindBugs considère le cas par défaut d'un switch
comme faisant partie du chemin d'exception puisque ce cas est souvent inattendu.
null
. Ceci peut conduire à une NullPointerException
quand le code sera exécuté.
]]>
null
est passée à une méthode qui déréférence ce paramètre de façon inconditionnelle. Cela peut se terminer en NullPointerException
.
]]>
null
est passée lors d'un appel alors que toutes les méthodes cibles possibles le déréférence inconditionnellement. Cela a de fortes chances de provoquer une NullPointerException
.
]]>
null
à une méthode qui peut déréférencer ce paramètre de façon inconditionnelle.
]]>
null
en paramètre d'une méthode qui a déclaré ce paramètre comme @NonNull
.
Notez que la méthode avec l'annotation @NonNull
peut être dans une sous-classe de l'objet appelé.
null
alors que cette méthode (ou une méthode dérivée d'une de ses classes mère) est déclarée comme renvoyant @NonNull
.
]]>
null
qui est déréférencée (sauf dans les chemins impliquant une RuntimeException).
]]>
static
de la classe crée une instance de la classe avant que tous les champs static final
soient alimentés.
]]>
finally
pour s'assurer de la fermeture des flux.
]]>
finally
pour garantir la fermeture des flux.
]]>
null
pour signaler qu'il n'y a pas de résultat (c'est-à-dire, une liste vide de résultats). De cette façon, aucune vérification explicite du null
n'est nécessaire dans les méthodes clientes.
D'un autre côté, utiliser null
signifie "il n'y a pas de réponse à cette question". Cela peut donc être approprié. Par exemple, File.listFiles()
renvoi une liste vide si un répertoire donné ne contient pas de fichiers, et renvoi null
si le fichier n'est pas un répertoire.
if (argv.length == 1); System.out.println("Hello, " + argv[0]);]]>
null
alors que cette valeur ne peut pas être à null
puisqu'elle a été déréférencée et qu'une NullPointerException
se serait alors produite à ce moment. Ce code est en contradiction avec le déréférencement préalable au sujet de la capacité de cette valeur d'être à null
. Soit le test est redondant, soit le déréférencement préalable est erroné.
]]>
null
.
]]>
null
.
]]>
null
.
]]>
null
. Deux types de comparaisons redondantes sont signalés :
null
null
et l'autre ne pourra jamais l'êtreCette alarme signale généralement qu'une variable connue pour être différente de null
est comparée avec null
. Bien que le test ne soit pas nécessaire, ce peut-être un simple cas de programmation défensive.
java.util.concurrent
), mais ne le libère pas dans tous les chemins d'exécution. En général, l'idiome correct pour utiliser un verrou JSR-166 est :
Lock l = ...; l.lock(); try { // do something } finally { l.unlock(); }]]>
java.util.concurrent
), mais ne le libère pas dans tous les chemins d'exception. En général, l'idiome correct pour utiliser un verrou JSR-166 est :
Lock l = ...; l.lock(); try { // do something } finally { l.unlock(); }]]>
==
ou !=
, alors que la façon correcte de comparer les instances de ce type est généralement d'utiliser la méthode equals()
. Des exemples de classes qui ne doivent généralement pas être comparées par référence sont java.lang.Integer
, java.lang.Float
, etc...
]]>
equals(Object)
pour deux références de type différents, sans sous-classe commune. Les objets comparés ne sont donc probablement pas de la même classe à l'éxécution (au moins que certaines classes de l'application n'aient pas été analysées ou qu'il y ait des chargements dynamiques). D'après le contrat de equals()
, les objets de classes différentes devraient toujours être inégaux, c'est pourquoi la comparaison a de fortes chances de toujours renvoyer false
à l'exécution.
]]>
equals(Object)
pour deux références d'interfaces sans rapport, aucune n'étant un sous-type de l'autre et aucune classe non abstraite implémentant les deux interfaces. Les objets comparés ne sont donc probablement pas de la même classe à l'éxécution (au moins que certaines classes de l'application n'aient pas été analysées ou qu'il y ait des chargements dynamiques). D'après le contrat de equals()
, les objets de classes différentes devraient toujours être inégaux.
]]>
equals(Object)
sur deux références, l'une de classe, l'autre d'interface, alors que ni la classe, ni aucune de ses sous classes abstraites n'implémente l'interface. Les objets comparés ne font donc probablement pas partie de la même hiérarchie de classe à l'exécution (à moins que certaines classes de l'application n'est pas été analysées ou soient chargées dynamiquement à l'exécution). En accord avec le contrat de equals()
, des objets de classes différentes doivent toujours être non égaux, donc le résultat de cette comparaison par java.lang.Object.equals(Object)
renverra systèmatiquement false
à l'exécution.
]]>
equals(Object)
, passant une valeur à null
comme argument. D'après le contrat de la méthode equals()
, cet appel devrait systématiquement renvoyer false
.
]]>
Object.wait()
sans détenir, visiblement, de verrou sur l'objet. Appeler wait()
sans détenir de verrou entraîne le déclenchement d'une IllegalMonitorStateException
.
]]>
Object.notify()
ou Object.notifyAll()
sans détenir, visiblement, de verrou sur l'objet. Appeler notify()
ou notifyAll()
sans détenir de verrou entraîne le déclenchement d'une IllegalMonitorStateException
.
]]>
public vida foo() { int x = 3; x = x; }
De telles affectations sont inutiles et peuvent indiquer une faute de frappe ou une erreur de logique.
]]>int x; public void foo() { x = x; }
De telles affectations sont inutiles et peuvent indiquer une faute de frappe ou une erreur logique.
]]>Random.nextInt(int)
.
]]>
En supposant que vous vouliez garantir que le résultat de votre opération ne soit pas négatif, vous devriez modifier votre code. Si le diviseur est une puissance de 2, vous pourriez utiliser un décalage binaire à la place (c'est-à-dire x.hashCode()&(n-1)
au lieu de x.hashCode()%n
). Cela est probablement plus rapide que de calculer le reste. Si le diviseur n'est pas une puissance de 2, vous devriez prendre la valeur absolue du reste (Math.abs(x.hashCode()%n)
).
x <= Integer.MAX_VALUE
).
]]>
exp % 1
) est assurée de toujours renvoyer 0. Vouliez-vous plutot dire (exp & 1)
ou (exp % 2)
?
]]>
&
C) avec D, qui est toujours inégale en raison des valeurs spécifiques des constantes C et D. Cela peut indiquer une faute de frappe ou une erreur logique.
]]>
&
0) avec 0, qui est toujours égale. Ceci peut indiquer une faute de frappe ou une erreur logique.
]]>
|
C) avec D, qui est toujours inégale en raison des valeurs spécifiques des constantes C et D. Ceci peut indiquer une erreur logique ou une faute de frappe.
Typiquement, ce bogue arrive quand du code essaye d'effectuer un test d'apparition d'un bit mais utilise l'opérateur OU ("|
") au lieu de l'opérateur ET ("&
").
volatile
. Comme le compilateur ou le processeur peuvent réordonner les instructions, les threads ne sont pas certains de voir un objet complètement initialisé, si la méthode peut-être appelée par de multiples threads. Vous pouvez rendre le champs volatile
pour corriger le problème. Pour plus d'informations, cf. site Web sur le modèle mémoire de Java.
]]>
volatile
. Comme le compilateur ou le processeur peuvent réordonner les instructions, les threads ne sont pas certains de voir un objet complètement initialisé, si la méthode peut-être appelée par de multiples threads. Vous pouvez rendre le champs volatile
pour corriger le problème. Pour plus d'informations, cf. site Web sur le modèle mémoire de Java.
]]>
java.util.concurrent.locks.Lock
. Vous devriez plutôt utiliser les méthodes lock()
et unlock()
.
]]>
RowSet
), ne l'affecte à aucun champ, ne la passe à aucune autre méthode, ne la renvoie pas, et ne semble pas la fermer dans tous les chemins d'exécution. Ne pas fermer une ressource base de données dans tous les chemins d'exécution peut entraîner de faibles performances et poser des problèmes de communication entre la base de données et l'application.
]]>
RowSet
), ne l'affecte à aucun champ, ne la passe à aucune autre méthode, ne la renvoie pas, et ne semble pas la fermer dans tous les chemins d'exception. Ne pas fermer une ressource base de données peut entraîner de faibles performances et poser des problèmes de communication entre la base de données et l'application.
]]>
String
est converti en StringBuffer
/StringBuilder
, complété, puis de nouveau converti en String
. Ceci a un coût exponentiel en fonction du nombre d'itérations, puisque la chaîne est recopiée à chaque itération.
De meilleurs performances peuvent être obtenues en utilisant explicitement StringBuffer
(ou StringBuilder
en Java 5).
Par exemple :
// C'est mal ! String s = ""; for (int i = 0; i < field.length; ++i) { s = s + field[i]; } // C'est mieux... StringBuffer buf = new StringBuffer(); for (int i = 0; i < field.length; ++i) { buf.append(field[i]); } String s = buf.toString();]]>
toArray()
d'une classe dérivant de Collection
, en lui passant en paramètre un tableau vide. Il est plus efficace d'utiliser myCollection.toArray(new Foo[myCollection.size()])
. Si le tableau transmis est assez grand pour stocker tous les éléments de la collection, alors il est alimenté et renvoyé directement. Ceci évite la nécessité de créer un nouveau tableau (par réflexion) pour renvoyer le résultat.
]]>
TestCase
de JUnit est implémente la méthode setUp()
. La méthode setUp()
devrait appeler super.setUp()
, mais ne le fait pas.
]]>
TestCase
de JUnit et implémente la méthode tearDown()
. La méthode tearDown()
devrait appeler super.tearDown()
, mais ne le fait pas.
]]>
TestCase
de JUnit et implémente une méthode suite()
. La méthode suite()
devrait-être déclarée comme étant static
, ce qui n'est pas fait.
]]>
TestCase
n'implémente aucune méthode de test.
]]>
Adapter
qui implémente un Listener
défini dans le paquetage java.awt.event
ou javax.swing.event
. En conséquence, cette méthode ne sera pas appelée quand l'évènement se produira.
]]>
getXXX()
ou updateXXX()
d'un ResultSet
est effectué avec l'index de champ 0. Comme l'index des champs de ResultSet
commence à 1 c'est toujours une erreur.
]]>
getXXX
ou updateXXX
d'un ResultSet
est réalisé pour l'indice 0. Puisque les indices de ResultSet
commencent à 1, c'est toujours une erreur.
]]>
setXXX
d'un PreparedStatement
est réalisé sur l'indice 0. Puisque les indices des paramêtres d'un PreparedStatement
commencent à 1, c'est toujours une erreur.
]]>
instanceof
alors que cela pourrait-être déterminé statiquement.
]]>
init()
de cette applet soit appelée, ces méthodes ne se comporteront pas correctement.
]]>
equals(Object o)
pour comparer un tableau et une référence qui ne semble pas être un tableau. Si les choses comparées sont de type différents, il est garanti qu'elles seront non égales et la comparaison est probablement une erreur. Même si les deux sont des tableaux, la méthode equals()
détermine seulement si les deux tableaux sont le même objet. Pour comparer le contenu de deux tableaux, utilisez java.util.Arrays.equals(Object[], Object[])
.
]]>
equals(Object o)
d'un tableau. Comme les tableaux ne surchargent pas la méthode equals()
de Object
, cet appel revient à comparer les adresses. Pour comparer les contenus de tableaux, utilisez java.util.Arrays.equals(Object[], Object[])
.
]]>
Thread.currentThread()
juste pour appeler la méthode interrupted()
. Comme interrupted()
est une méthode statique, il est plus simple et facile d'utiliser Thread.interrupted()
.
]]>
Thread.interrupted()
sur un objet Thread
qui n'est pas le thread actif. Pusique la méthode interrupted()
est statique, la méthode interrupted()
sera appelée sur un objet différent de celui auquel l'auteur du code pensait.
]]>
Notez que le compilateur javac de Sun génère fréquemment ce genre d'affectations à perte. FindBugs analysant le byte-code généré, il n'y a pas de façon simple d'éliminer ces fausses alarmes.
]]>Map
au moyen d'une clé provenant d'un itérateur sur keySet
. Il est plus efficace d'utiliser un itérateur sur l'entrySet
de la Map
, pour éviter la recherche par Map.get(clé)
.
]]>
try-catch
qui intercepte les objets Exception
, mais Exception
n'est jamais déclenché dans ce bloc, et RuntimeException
n'est pas explicitement intercepté. C'est une erreur commune de dire que try / catch (Exception e)
est identique à plusieurs try / catch
, mais cette tournure intercepte également les RuntimeException
, masquant des bugs potentiels.
]]>
if (x == Double.NaN)
). La sémantique de NaN
fait que, par définition, aucune valeur n'est égale à Nan
, y compris NaN
. Donc x == Double.NaN
renvoi systématiquement false
.
Pour savoir si la valeur contenu dans x
est la valeur particulière "Not A Number", utilisez Double.isNaN(x)
(ou Float.isNaN(x)
si x
est en simple précision).
BigDecimal
. Pour les valeurs qui n'ont pas besoin d'être précises, pensez à tester l'égalité sur une portée quelconque, par exemple : if ( Math.abs(x - y) < .0000001 )
. Cf section 4.2.4 des spécifications du langage Java.
]]>
java.lang.Math
sur une valeur constante. Dans ce cas, le résultat de cet appel peut être déterminé statiquement, ce qui est plus rapide et souvent plus précis. Les méthodes détectées sont :
Méthode | Paramètre |
---|---|
abs | -tous- |
acos | 0.0 ou 1.0 |
asin | 0.0 ou 1.0 |
atan | 0.0 ou 1.0 |
atan2 | 0.0 |
cbrt | 0.0 ou 1.0 |
ceil | -tous- |
cos | 0.0 |
cosh | 0.0 |
exp | 0.0 ou 1.0 |
expm1 | 0.0 |
floor | -tous- |
log | 0.0 ou 1.0 |
log10 | 0.0 ou 1.0 |
rint | -tous- |
round | -tous- |
sin | 0.0 |
sinh | 0.0 |
sqrt | 0.0 ou 1.0 |
tan | 0.0 |
tanh | 0.0 |
toDegrees | 0.0 ou 1.0 |
toRadians | 0.0 |
Action
Struts, et utilise une variable de cette instance. Puisqu'une seule instance de la classe Action
Struts est créée par le cadre de travail Struts, et est utilisée dans un environnement multitâche, ce paradigme est très fortement découragé et très certainement problématique. Considérer l'emploi seul de variables propres à la méthode.
]]>
Servlet
, et utilise une variable de l'instance. Puisqu'une seule instance d'une classe Servlet
est créée par le cadre de travail J2EE, et est utilisée dans un environnement multitâche, ce paradigme est très fortement découragé et très certainement problématique. Considérer l'emploi seul de variables propres à la méthode.
]]>
wait()
, notify()
or notifyAll()
sur elle-même (la référence this
). Les classes qui utilise cette classes peuvent de plus utiliser une instance de cette classe comme un objet de synchronisation. Du fait que deux classes peuvent utiliser le même objet pour la synchronisation, la cohérence en environnement multitâche devient suspecte. Vous ne devriez synchroniser ni appeler de méthodes de sémaphores sur une référence publique. Considérer l'utilisation d'une varible interne privée pour contrôler la synchronisation.
]]>
long
, comme dans :
long convertDaysToMilliseconds(int days) { return 1000*3600*24*days; }
. Si la multiplication était réalisée en utilisant l'arithmétique long
, vous pourriez éviter le risque de débordement de capacité du calcul. Vous pouvez par exemple corriger le code précédent par : long convertDaysToMilliseconds(int days) { return 1000L*3600*24*days; }
ou
static final long MILLISECONDS_PER_DAY = 24L*3600*1000;
long convertDaysToMilliseconds(int days) { return days * MILLISECONDS_PER_DAY; }
]]>
Math.round()
qui renvoi l'int
ou le long
le plus proche de son paramètre. Cette opération doit toujours revenir à ne rien faire, puisque le transtypage d'un entier en un flottant devrait systématiquement donner un flottant sans partie décimale. Il est probable que l'opération gérant la valeur passée à Math.round()
devrait être effectuée en arithmétique flottante.
]]>
Math.ceil()
, qui arrondit un nombre flottant à sa valeur entière immédiatement supérieure. Cette opération n'a pas de raison d'être, puisque le transtypage d'un entier en double donne un nombre sans valeur après la virgule. Il est vraissemblable que l'opération qui a créé la valeur pour la passer à Math.ceil
visait l'utilisation de l'arithmétique sur un nombre flottant en double précision.
]]>
double
suggère que cette précision était voulue dès le départ. Peut être l'un ou l'autre des opérandes, ou les deux opérandes, auraient du être transtypé avant d'effectuer la division. Voici un exemple :
]]>int x = 2; int y = 5; // Faux: renvoi 0.0 double value1 = x / y; // Juste: renvoi 0.4 double value2 = x / (double) y;
HttpSession
. Une erreur se produira si cette session est rendue passive ou migrée.
]]>
ObjectOutput.writeObject
. Une erreur se produira si cet objet est effectivement non sérialisable.
]]>
Collection
vers un type de collection abstrait (tel que Collection
). Assurez vous que l'objet est bien du type précisé. Si vous désirez par exemple faire une itération sur une collection, le transtypage vers Set
ou List
est inutile.
]]>
ClassCastException
.
]]>
instanceof
renverra systématiquement false
, puisqu'il est garanti que la valeur testée sera à null
. Bien que ce test soit sûr, il est probable qu'il indique une incompréhension ou une erreur de logique.
]]>
instanceof
renverra toujours faux. Même s'il est sûr, assurez-vous qu'il ne s'agisse pas d'une erreur logique ou d'une mauvaise compréhension.
]]>
instanceof
renverra toujours vrai. Même s'il est sûr, assurez-vous qu'il ne s'agit pas d'une erreur logique ou d'une mauvaise compréhension.
]]>
Collection
, List
, ou Set
) vers une implémentation concrète spécifique (telles que ArrayList
ou HashSet
). Ceci n'est pas forcément correct, et peut rendre votre code plus fragile, puisqu'il un éventuel refactoring futur avec une autre implémentation concrète plus difficile. A défaut d'une raison valable, l'utilisation des classes abstraites est recommandée.
]]>
String
attendant une expression régulière reçoit "." en paramètre. Est-ce voulu ? Par exemple, s.replaceAll(".", "/")
renverra une chaine dont chaque caractère aura été remplacé par le caractère '/'.
]]>
PatternSyntaxException
sera lancée.
]]>
i++
) et en annule immédiatement l'effet. Par exemple, i = i++
réécrit de façon immédiate la valeur incrémentée avec la valeur originale.
]]>
short
ou un byte
, ce qui élimine les bits supérieurs du résultat. Puisque les bits supérieurs sont éliminés, il peut ne pas y avoir de différence entre un décalage à droite signé ou non signé (ceci dépend de la taille du décalage)
]]>
i % 60 * 1000
correspond à (i % 60) * 1000
, non à i % (60 * 1000)
.
]]>
toString
sur un tableau, ce qui va générer un résultat assez inutile du genre [C@16f0472
. Envisagez d'utiliser String.valueOf
pour convertir un tableau en une chaine lisible contenant les valeurs du tableau. Cf Programming Puzzlers, chapitre 3, problème 12.
]]>
(low+high) >>> 1
au lieu de (low+high)/2
.
Le bug existe dans de nombreuses implémentations des recherches binaires et des tris fusion. Martin Buchholz l'a recherché et corrigé dans les librairies du JDK et Joshua Bloch a largement publié ce modèle de bug.
]]>x % 2 == 1
pour véifier si une valeur est impaire, mais cela ne fonctionera pas avec une valeur négative (Ex. : (-5) % 2 == -1
). Si ce code doit tester si une valeur est impaire, envisagez d'utiliser x & 1 == 1
ou x % 2 != 0
.
]]>
File
en utilisant un chemin absolu de fichier codé en dur (Ex. : new File("/home/dannyc/workspace/j2ee/src/share/com/sun/enterprise/deployment");)
.
]]>
substring(0)
sur une chaine, ce qui renvoit la valeur originale.
]]>
hasNext()
appelle la méthode next()
. C'est très probablement faux puisque la méthode hasNext()
n'est pas changer l'état de l'itérateur tandis que la méthode next()
doit changer cet état.
]]>
Thread.sleep()
en tenant un verrou. Ceci peut résulter en de faibles performances, peu de capacité à monter en charge ou un inter-blocage puisque d'autres processus pourraient être en attente du verrou. C'est une meilleure idée d'appeler wait()
sur le verrou, afin de le libérer et de permettre à d'autre processus de tourner.
]]>
switch
. Ce peut être normal mais il vaut mieux vérifier que ce n'est pas une erreur de codage.
]]>
final
mais comporte des champs protected
. Cette classe étant finale, elle ne pourra jamais être dérivée et donc l'utilisation de protected
est troublante. Le modificateur d'accès devrait être modifié à private
ou public
pour mettre en évidence la véritable utilisation du champ.
]]>
true
ou false
) à une variable booléenne dans une expression if
ou while
. Il est probable que le but était d'effectuer une comparaison booléenne utilisant ==
et non pas une affectation avec =
.
]]>