Style de code Java AOSP pour les contributeurs

Les styles de code sur cette page sont des règles strictes pour la contribution de code Java au projet Android Open Source (AOSP). Contributions à la plate - forme Android qui ne respectent pas ces règles ne sont généralement pas acceptées. Nous reconnaissons que tout le code existant ne suit pas ces règles, mais nous nous attendons à ce que tout nouveau code soit conforme. Voir codage à l' égard des exemples de la terminologie à utiliser et éviter pour un écosystème plus inclusif.

Être cohérent

L'une des règles les plus simples est SOYEZ COHÉRENT. Si vous modifiez du code, prenez quelques minutes pour examiner le code environnant et déterminer son style. Si ce code utilise des espaces autour des if des clauses, vous devriez, aussi. Si les commentaires du code sont entourés de petites cases d'étoiles, faites en sorte que vos commentaires aient également de petites cases d'étoiles autour d'eux.

L'intérêt d'avoir des directives de style est d'avoir un vocabulaire de codage commun, afin que les lecteurs puissent se concentrer sur ce que vous dites, plutôt que sur la façon dont vous le dites. Nous présentons ici des règles de style globales pour que vous connaissiez le vocabulaire, mais le style local est également important. Si le code que vous ajoutez à un fichier semble radicalement différent du code existant qui l'entoure, cela déstabilise les lecteurs lorsqu'ils le lisent. Essayez d'éviter cela.

Règles du langage Java

Android suit les conventions de codage Java standard avec les règles supplémentaires décrites ci-dessous.

Ne pas ignorer les exceptions

Il peut être tentant d'écrire du code qui ignore une exception, comme :

  void setServerPort(String value) {
      try {
          serverPort = Integer.parseInt(value);
      } catch (NumberFormatException e) { }
  }

Ne fais pas ça. Bien que vous puissiez penser que votre code ne rencontrera jamais cette condition d'erreur ou qu'il n'est pas important de la gérer, ignorer ce type d'exception crée des mines dans votre code pour que quelqu'un d'autre déclenche un jour. Vous devez gérer chaque exception dans votre code d'une manière raisonnée ; la manipulation spécifique varie selon les cas.

«Chaque fois que quelqu'un a une clause catch vide , ils devraient avoir un sentiment effrayant. Il y a certainement des moments où il est en fait la bonne chose à faire, mais au moins vous devez penser. En Java , vous ne pouvez pas échapper au sentiment effrayant. "- James Gosling

Les alternatives acceptables (par ordre de préférence) sont :

  • Jetez l'exception à l'appelant de votre méthode.
      void setServerPort(String value) throws NumberFormatException {
          serverPort = Integer.parseInt(value);
      }
    
  • Lancez une nouvelle exception appropriée à votre niveau d'abstraction.
      void setServerPort(String value) throws ConfigurationException {
        try {
            serverPort = Integer.parseInt(value);
        } catch (NumberFormatException e) {
            throw new ConfigurationException("Port " + value + " is not valid.");
        }
      }
    
  • Gérer l'erreur grâce et remplacer une valeur appropriée dans la catch {} bloc.
      /** Set port. If value is not a valid number, 80 is substituted. */
    
      void setServerPort(String value) {
        try {
            serverPort = Integer.parseInt(value);
        } catch (NumberFormatException e) {
            serverPort = 80;  // default port for server
        }
      }
    
  • Intercepter l'exception et lancer une nouvelle instance de RuntimeException . C'est dangereux, alors ne le faites que si vous êtes certain que si cette erreur se produit, la chose appropriée à faire est de planter.
      /** Set port. If value is not a valid number, die. */
    
      void setServerPort(String value) {
        try {
            serverPort = Integer.parseInt(value);
        } catch (NumberFormatException e) {
            throw new RuntimeException("port " + value " is invalid, ", e);
        }
      }
    
  • En dernier recours, si vous êtes sûr qu'ignorer l'exception est approprié, vous pouvez l'ignorer, mais vous devez également expliquer pourquoi avec une bonne raison.
    /** If value is not a valid number, original port number is used. */
    
    void setServerPort(String value) {
        try {
            serverPort = Integer.parseInt(value);
        } catch (NumberFormatException e) {
            // Method is documented to just ignore invalid user input.
            // serverPort will just be unchanged.
        }
    }
    

Ne pas intercepter les exceptions génériques

Il peut être tentant d'être paresseux lors de la capture d'exceptions et de faire quelque chose comme ceci :

  try {
      someComplicatedIOFunction();        // may throw IOException
      someComplicatedParsingFunction();   // may throw ParsingException
      someComplicatedSecurityFunction();  // may throw SecurityException
      // phew, made it all the way
  } catch (Exception e) {                 // I'll just catch all exceptions
      handleError();                      // with one generic handler!
  }

Ne fais pas ça. Dans presque tous les cas, il est inapproprié d'attraper générique Exception ou Throwable ( de préférence pas Throwable car il inclut Error exceptions). Il est dangereux , car cela signifie que les exceptions ne vous prévu (y compris les exceptions d'exécution comme ClassCastException ) se coincer dans la gestion des erreurs au niveau de l' application. Cela masque les propriétés de gestion des échecs de votre code, ce qui signifie que si quelqu'un ajoute un nouveau type d'exception dans le code que vous appelez, le compilateur ne signalera pas que vous devez gérer l'erreur différemment. Dans la plupart des cas, vous ne devriez pas gérer différents types d'exceptions de la même manière.

La rare exception à cette règle est le code de test et le code de niveau supérieur où vous souhaitez détecter toutes sortes d'erreurs (pour les empêcher de s'afficher dans une interface utilisateur ou pour maintenir un travail par lots en cours d'exécution). Dans ce cas, vous pouvez attraper générique Exception (ou Throwable ) et gérer de façon appropriée l'erreur. Réfléchissez bien avant de faire cela, cependant, et mettez des commentaires expliquant pourquoi c'est sûr dans ce contexte.

Alternatives à la capture d'exceptions génériques :

  • Attraper chaque exception séparément en tant que partie d'un bloc-prises multiples, par exemple:
    try {
        ...
    } catch (ClassNotFoundException | NoSuchMethodException e) {
        ...
    }
  • Refactorisez votre code pour avoir une gestion des erreurs plus fine, avec plusieurs blocs try. Séparez les E/S de l'analyse et gérez les erreurs séparément dans chaque cas.
  • Rejetez l'exception. Plusieurs fois, vous n'avez pas besoin d'intercepter l'exception à ce niveau de toute façon, laissez simplement la méthode la lancer.

N'oubliez pas que les exceptions sont vos amies ! Lorsque le compilateur se plaint que vous n'attrapez pas d'exception, ne vous renfrognez pas. Le sourire! Le compilateur vous a simplement permis de détecter plus facilement les problèmes d'exécution dans votre code.

N'utilisez pas de finaliseurs

Les finaliseurs sont un moyen d'exécuter un morceau de code lorsqu'un objet est ramassé. Alors que les finaliseurs peuvent être utiles pour le nettoyage (en particulier des ressources externes), il n'y a aucune garantie quant au moment où un finaliseur sera appelé (ou même qu'il sera appelé du tout).

Android n'utilise pas de finaliseurs. Dans la plupart des cas, vous pouvez utiliser une bonne gestion des exceptions à la place. Si vous avez absolument besoin d' un finaliseur, définir un close() méthode (ou similaire) et documenter exactement quand que les besoins de la méthode à appeler (voir InputStream pour un exemple). Dans ce cas, il est approprié mais pas obligatoire d'imprimer un court message de journal à partir du finaliseur, tant qu'il n'est pas prévu d'inonder les journaux.

Importations complètes

Lorsque vous souhaitez utiliser la classe Bar du package foo , il y a deux façons possibles pour importer:

  • import foo.*;

    Réduit potentiellement le nombre d'instructions d'importation.

  • import foo.Bar;

    Rend évident quelles classes sont utilisées et le code est plus lisible pour les mainteneurs.

Utilisez l' import foo.Bar; pour importer tout le code Android. Une exception est explicitement Java bibliothèques standard ( java.util.* , java.io.* , etc.) et le code de test unitaire ( junit.framework.* ).

Règles de la bibliothèque Java

Il existe des conventions pour l'utilisation des bibliothèques et des outils Java d'Android. Dans certains cas, la convention a changé de manière importante et le code plus ancien peut utiliser un modèle ou une bibliothèque obsolète. Lorsque vous travaillez avec un tel code, vous pouvez continuer le style existant. Cependant, lors de la création de nouveaux composants, n'utilisez jamais de bibliothèques obsolètes.

Règles de style Java

Utiliser les commentaires standard Javadoc

Chaque fichier doit avoir une déclaration de copyright en haut, suivie des déclarations de package et d'importation (chaque bloc étant séparé par une ligne vide), et enfin la déclaration de classe ou d'interface. Dans les commentaires Javadoc, décrivez ce que fait la classe ou l'interface.

/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.foo;

import android.os.Blah;
import android.view.Yada;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Does X and Y and provides an abstraction for Z.
 */

public class Foo {
    ...
}

Chaque classe et méthode publique non négligeable que vous écrivez doit contenir un commentaire Javadoc avec au moins une phrase décrivant ce que la classe ou méthode ne. Cette phrase doit commencer par un verbe descriptif à la troisième personne.

Exemples

/** Returns the correctly rounded positive square root of a double value. */

static double sqrt(double a) {
    ...
}

ou

/**
 * Constructs a new String by converting the specified array of
 * bytes using the platform's default character encoding.
 */
public String(byte[] bytes) {
    ...
}

Vous n'avez pas besoin de Javadoc d'écriture pour obtenir les triviales et fixer des méthodes telles que setFoo() si tous vos Javadoc dirait est « ensembles Foo ». Si la méthode fait quelque chose de plus complexe (comme l'application d'une contrainte ou a un effet secondaire important), alors vous devez la documenter. Si la signification de la propriété "Foo" n'est pas évidente, vous devez la documenter.

Chaque méthode que vous écrivez, publique ou autre, bénéficierait de Javadoc. Les méthodes publiques font partie d'une API et nécessitent donc Javadoc. Android n'applique pas un style spécifique pour écrire des commentaires Javadoc, mais vous devez suivre les instructions Comment écrire Doc Commentaires pour l'outil Javadoc .

Écrire des méthodes courtes

Lorsque cela est possible, gardez les méthodes petites et ciblées. Nous reconnaissons que les méthodes longues sont parfois appropriées, donc aucune limite stricte n'est imposée sur la longueur des méthodes. Si une méthode dépasse 40 lignes environ, demandez-vous si elle peut être décomposée sans nuire à la structure du programme.

Définir des champs dans des emplacements standard

Définissez les champs soit en haut du fichier, soit juste avant les méthodes qui les utilisent.

Limiter la portée de la variable

Gardez la portée des variables locales au minimum. Cela augmente la lisibilité et la maintenabilité de votre code et réduit la probabilité d'erreur. Déclarez chaque variable dans le bloc le plus interne qui englobe toutes les utilisations de la variable.

Déclarez les variables locales au point où elles sont utilisées pour la première fois. Presque toutes les déclarations de variables locales doivent contenir un initialiseur. Si vous n'avez pas encore assez d'informations pour initialiser une variable de manière sensée, retardez la déclaration jusqu'à ce que vous le fassiez.

L'exception concerne les instructions try-catch. Si une variable est initialisée avec la valeur de retour d'une méthode qui lève une exception vérifiée, elle doit être initialisée à l'intérieur d'un bloc try. Si la valeur doit être utilisée en dehors du bloc try, elle doit être déclarée avant le bloc try, où elle ne peut pas encore être correctement initialisée :

// Instantiate class cl, which represents some sort of Set

Set s = null;
try {
    s = (Set) cl.newInstance();
} catch(IllegalAccessException e) {
    throw new IllegalArgumentException(cl + " not accessible");
} catch(InstantiationException e) {
    throw new IllegalArgumentException(cl + " not instantiable");
}

// Exercise the set
s.addAll(Arrays.asList(args));

Cependant, vous pouvez même éviter ce cas en encapsulant le bloc try-catch dans une méthode :

Set createSet(Class cl) {
    // Instantiate class cl, which represents some sort of Set
    try {
        return (Set) cl.newInstance();
    } catch(IllegalAccessException e) {
        throw new IllegalArgumentException(cl + " not accessible");
    } catch(InstantiationException e) {
        throw new IllegalArgumentException(cl + " not instantiable");
    }
}

...

// Exercise the set
Set s = createSet(cl);
s.addAll(Arrays.asList(args));

Déclarez les variables de boucle dans l'instruction for elle-même, à moins qu'il n'y ait une raison impérieuse de faire autrement :

for (int i = 0; i < n; i++) {
    doSomething(i);
}

et

for (Iterator i = c.iterator(); i.hasNext(); ) {
    doSomethingElse(i.next());
}

Déclarations d'importation de commande

L'ordre des déclarations d'importation est :

  1. Importations Android
  2. Les importations en provenance des tiers ( com , junit , net , org )
  3. java et javax

Pour correspondre exactement aux paramètres IDE, les importations doivent être :

  • Alphabétique au sein de chaque groupe, avec des majuscules avant les minuscules (par exemple, Z avant a)
  • Séparés par une ligne blanche entre chaque grand groupe ( android , com , junit , net , org , java , javax )

À l'origine, il n'y avait aucune exigence de style sur la commande, ce qui signifie que les IDE changeaient toujours la commande ou que les développeurs IDE devaient désactiver les fonctionnalités de gestion automatique des importations et maintenir manuellement les importations. Cela a été jugé mauvais. Lorsque le style Java a été demandé, les styles préférés variaient énormément et Android devait simplement "choisir une commande et être cohérent". Nous avons donc choisi un style, mis à jour le guide de style et fait en sorte que les IDE lui obéissent. Nous nous attendons à ce que, lorsque les utilisateurs de l'IDE travaillent sur le code, les importations dans tous les packages correspondent à ce modèle sans effort d'ingénierie supplémentaire.

Nous avons choisi ce style tel que :

  • Les importations que les gens veulent regarder en premier ont tendance à être en haut ( android ).
  • Les importations que les gens veulent regarder au moins ont tendance à être au fond ( java ).
  • Les humains peuvent facilement suivre le style.
  • Les IDE peuvent suivre le style.

Mettez les importations statiques au-dessus de toutes les autres importations commandées de la même manière que les importations régulières.

Utiliser des espaces pour l'indentation

Nous utilisons quatre (4) retraits d'espace pour les blocs et jamais les tabulations. En cas de doute, soyez cohérent avec le code environnant.

Nous utilisons huit (8) retraits d'espace pour les retours à la ligne, y compris les appels de fonction et les affectations.

conseillé

Instrument i =
        someLongExpression(that, wouldNotFit, on, one, line);

Non recommandé

Instrument i =
    someLongExpression(that, wouldNotFit, on, one, line);

Respecter les conventions de nommage des champs

  • Non publiques, les noms de champs non statiques commencent par m .
  • Noms de champs statiques commencent par s .
  • Les autres champs commencent par une lettre minuscule.
  • Champs statiques publics (finales constantes) sont ALL_CAPS_WITH_UNDERSCORES .

Par exemple:

public class MyClass {
    public static final int SOME_CONSTANT = 42;
    public int publicField;
    private static MyClass sSingleton;
    int mPackagePrivate;
    private int mPrivate;
    protected int mProtected;
}

Utiliser le style d'accolade standard

Mettez des accolades sur la même ligne que le code qui les précède, pas sur leur propre ligne :

class MyClass {
    int func() {
        if (something) {
            // ...
        } else if (somethingElse) {
            // ...
        } else {
            // ...
        }
    }
}

Nous avons besoin d'accolades autour des instructions pour un conditionnel. Exception : si le conditionnel entier (la condition et le corps) tient sur une seule ligne, vous pouvez (mais n'êtes pas obligé de) le mettre sur une seule ligne. Par exemple, ceci est acceptable :

if (condition) {
    body();
}

et c'est acceptable :

if (condition) body();

mais ce n'est pas acceptable :

if (condition)
    body();  // bad!

Limiter la longueur de ligne

Chaque ligne de texte de votre code ne doit pas dépasser 100 caractères. Alors que beaucoup de discussions a entouré cette règle, la décision demeure pas moins que 100 caractères est le maximum avec les exceptions suivantes:

  • Si une ligne de commentaire contient un exemple de commande ou une URL littérale de plus de 100 caractères, cette ligne peut comporter plus de 100 caractères pour faciliter le copier-coller.
  • Les lignes d'importation peuvent dépasser la limite car les humains les voient rarement (cela simplifie également l'écriture d'outils).

Utiliser des annotations Java standard

Les annotations doivent précéder les autres modificateurs pour le même élément de langage. Annotations de marqueurs simples (par exemple, @Override ) peuvent être inscrits sur la même ligne avec l'élément de langage. S'il existe plusieurs annotations ou annotations paramétrées, répertoriez-les une par ligne par ordre alphabétique.

Les pratiques standard Android pour les trois annotations prédéfinies en Java sont :

  • Utilisez la @Deprecated annotation chaque fois que l'utilisation de l'élément annoté est déconseillée. Si vous utilisez la @Deprecated annotation, vous devez également avoir une @deprecated étiquette Javadoc et il devrait nommer une autre mise en oeuvre. De plus, rappelez - vous qu'une @Deprecated méthode est encore censé fonctionner. Si vous voyez ancien code qui a une @deprecated balise Javadoc, ajoutez la @Deprecated annotation.
  • Utilisez la @Override annotation chaque fois qu'une méthode remplace la déclaration ou la mise en œuvre d'une superclasse. Par exemple, si vous utilisez la @inheritdocs balise Javadoc, et proviennent d'une classe (pas d'interface), vous devez également annoter que la méthode remplace la méthode de la classe parente.
  • Utilisez la @SuppressWarnings annotation que dans des circonstances où il est impossible d'éliminer un avertissement. Si un avertissement passe ce test « impossible d'éliminer », l' @SuppressWarnings annotation doit être utilisée pour faire en sorte que tous les avertissements reflètent les problèmes réels dans le code.

    Lorsqu'un @SuppressWarnings annotation est nécessaire, il doit être préfixé avec un TODO commentaire qui explique le « impossible d'éliminer » condition. Cela identifie normalement une classe incriminée qui a une interface maladroite. Par exemple:

    // TODO: The third-party class com.third.useful.Utility.rotate() needs generics
    @SuppressWarnings("generic-cast")
    List<String> blix = Utility.rotate(blax);
    

    Lorsqu'un @SuppressWarnings annotation est nécessaire, factoriser le code pour isoler les éléments logiciels où l'annotation applique.

Traiter les acronymes comme des mots

Traitez les acronymes et les abréviations comme des mots dans les variables de nommage, les méthodes et les classes pour rendre les noms plus lisibles :

Bon Mauvais
XmlHttpRequête XMLHTTPRequête
getCustomerId obtenirIDClient
classe Html classe HTML
URL de chaîne URL de chaîne
identifiant long ID long

Comme les bases de code JDK et Android sont incohérentes autour des acronymes, il est pratiquement impossible d'être cohérent avec le code environnant. Par conséquent, traitez toujours les acronymes comme des mots.

Utiliser les commentaires TODO

Utiliser TODO commentaires pour le code qui est temporaire, une solution à court terme, ou assez bon , mais pas parfait. Ces commentaires devraient inclure la chaîne TODO en majuscules, suivi par deux points:

// TODO: Remove this code after the UrlTable2 has been checked in.

et

// TODO: Change this to use a flag instead of a constant.

Si votre TODO est de la forme « A une date ultérieure faire quelque chose » assurez - vous que vous incluez soit une date spécifique ( « Fix par Novembre 2005 ») ou d' un événement spécifique ( « Supprimer ce code après tous les mélangeurs de production comprennent le protocole V7. » ).

Connectez-vous avec parcimonie

Bien que la journalisation soit nécessaire, elle a un impact négatif sur les performances et perd de son utilité si elle n'est pas raisonnablement concise. Les fonctions de journalisation offrent cinq niveaux de journalisation différents :

  • ERROR : Utilisez quand quelque chose de fatal est arrivé, qui est, quelque chose aura des conséquences visibles par l' utilisateur et ne seront pas récupérables sans supprimer certaines données, applications désinstallation, effaçant les partitions de données ou flashage l'ensemble du dispositif (ou pire). Ce niveau est toujours enregistré. Les questions qui justifient une exploitation forestière au ERROR niveau sont de bons candidats à signaler à un serveur de collecte de statistiques.
  • WARNING : Utiliser quand est arrivé quelque chose de grave et inattendu, qui est, ce qui aura des conséquences visibles par l' utilisateur , mais est probablement récupérable sans perte de données en effectuant une action explicite, allant de l' attente ou de redémarrer une application tout le chemin de re-téléchargement une nouvelle version d'une application ou en redémarrant l'appareil. Ce niveau est toujours enregistré. Les questions qui justifient d' exploitation forestière au WARNING niveau pourraient également être pris en considération pour les rapports à un serveur de collecte de statistiques.
  • INFORMATIVE : Permet de noter que intéressant est arrivé quelque chose, qui est, quand une situation est détectée qui est susceptible d'avoir un large impact, mais est pas nécessairement une erreur. Une telle condition ne doit être enregistrée que par un module qui pense qu'il fait le plus autorité dans ce domaine (pour éviter une journalisation en double par des composants ne faisant pas autorité). Ce niveau est toujours enregistré.
  • DEBUG : Utiliser de noter en outre ce qui se passe sur l'appareil qui pourrait être pertinent d'enquêter et de débogage des comportements inattendus. Enregistrez uniquement ce qui est nécessaire pour rassembler suffisamment d'informations sur ce qui se passe avec votre composant. Si vos journaux de débogage dominent le journal, vous devez utiliser la journalisation détaillée.

    Ce niveau est enregistré même sur la libération construit et doit être entouré d'un if (LOCAL_LOG) ou if LOCAL_LOGD) bloc, où LOCAL_LOG[D] est défini dans votre classe ou sous - composant, pour qu'il y ait une possibilité de désactiver toutes ces journalisation . Par conséquent, il doit y avoir aucune logique active dans un if (LOCAL_LOG) bloc. Tout le bâtiment de chaîne pour le journal doit également être placé à l' intérieur if (LOCAL_LOG) bloc. Ne pas factoriser l'appel d'enregistrement sur dans un appel de méthode si elle va faire la chaîne pour la construction de lieu en dehors du if (LOCAL_LOG) bloc.

    Il y a un code qui dit encore if (localLOGV) . Ceci est également considéré comme acceptable, bien que le nom ne soit pas standard.

  • VERBOSE : utilisation pour tout le reste. Ce niveau est connecté uniquement debug et devrait être entouré d'un if (LOCAL_LOGV) bloc (ou équivalent) afin qu'il puisse être compilé par défaut. Tout bâtiment de chaîne est extirpé de la libération construit et doit apparaître dans le if (LOCAL_LOGV) bloc.

Remarques

  • Au sein d' un module donné, autre que le VERBOSE niveau, une erreur ne doit être signalée une fois si possible. Dans une seule chaîne d'appels de fonction au sein d'un module, seule la fonction la plus interne doit renvoyer l'erreur, et les appelants dans le même module ne doivent ajouter de la journalisation que si cela aide de manière significative à isoler le problème.
  • Dans une chaîne de modules, autre que le VERBOSE niveau, lorsqu'un module de niveau inférieur détecte des données non valides provenant d'un module de niveau supérieur, le module de niveau inférieur ne devrait connecter cette situation au DEBUG journal, et seulement si fournit l' exploitation forestière informations qui ne sont pas autrement disponibles pour l'appelant. Plus précisément, il n'est pas nécessaire de consigner les situations où une exception est levée (l'exception doit contenir toutes les informations pertinentes) ou où la seule information consignée est contenue dans un code d'erreur. Ceci est particulièrement important dans l'interaction entre le cadre et les applications, et les conditions causées par des applications tierces qui sont correctement traitées par le cadre ne devrait pas déclencher l' exploitation forestière plus élevé que le DEBUG niveau. Les seules situations qui doivent déclencher l' enregistrement au INFORMATIVE niveau ou est plus élevé quand un module ou une application détecte une erreur à son propre niveau ou en provenance d'un niveau inférieur.
  • Lorsqu'une condition qui justifierait normalement une journalisation est susceptible de se produire plusieurs fois, il peut être judicieux d'implémenter un mécanisme de limitation du débit pour empêcher le débordement des journaux avec de nombreuses copies en double des mêmes informations (ou très similaires).
  • Les pertes de connectivité réseau sont considérées comme courantes et sont pleinement attendues, et ne doivent pas être enregistrées gratuitement. Une perte de connectivité réseau qui a des conséquences au sein d' une application doit être connecté au DEBUG ou VERBOSE niveau (selon que les conséquences sont suffisamment graves et assez inattendu pour être connecté dans une version release).
  • Le fait d'avoir un système de fichiers complet sur un système de fichiers accessible à ou au nom d'applications tierces ne doit pas être enregistré à un niveau supérieur à INFORMATIVE.
  • Des données non valides provenant d'une source non fiable (y compris tous les fichiers sur un stockage partagé, ou des données provenant via une connexion réseau) est considéré comme prévu et ne devrait pas entraîner une exploitation forestière à un niveau plus élevé que DEBUG quand il est détecté invalide (et encore l' exploitation forestière doit être aussi limité que possible).
  • Lorsqu'il est utilisé sur String objets, le + opérateur crée implicitement un StringBuilder exemple avec la taille de la mémoire tampon par défaut (16 caractères) et éventuellement d' autres temporaires String objets. Ainsi , la création explicitement StringBuilder objets ne sont pas plus cher que de compter sur la valeur par défaut + opérateur (et peut être beaucoup plus efficace). Gardez à l' esprit que le code qui appelle Log.v() est compilé et exécuté sur la libération construit, y compris la construction des chaînes, même si les journaux ne sont pas en cours de lecture.
  • Toute journalisation destinée à être lue par d'autres personnes et disponible dans les versions de version doit être laconique sans être cryptique et doit être compréhensible. Cela inclut tout de l' exploitation forestière au DEBUG niveau.
  • Dans la mesure du possible, continuez à vous connecter sur une seule ligne. Des longueurs de ligne allant jusqu'à 80 ou 100 caractères sont acceptables. Évitez les longueurs supérieures à environ 130 ou 160 caractères (y compris la longueur de la balise) si possible.
  • Si l' exploitation forestière succès de rapports, ne jamais utiliser à des niveaux plus élevés que VERBOSE .
  • Si vous utilisez l' enregistrement temporaire pour diagnostiquer un problème qui est difficile à reproduire, le garder au DEBUG ou VERBOSE niveau et le joindre à si les blocs qui permettent de le désactiver au moment de la compilation.
  • Faites attention aux fuites de sécurité à travers le journal. Évitez de consigner des informations privées. En particulier, évitez de consigner des informations sur le contenu protégé. Ceci est particulièrement important lors de l'écriture de code framework car il n'est pas facile de savoir à l'avance ce qui sera et ne sera pas une information privée ou un contenu protégé.
  • Ne jamais utiliser System.out.println() (ou printf() pour le code natif). System.out et System.err redirigés vers /dev/null , vos déclarations d'impression ont pas d' effets visibles. Cependant, toute la construction de chaîne qui se produit pour ces appels est toujours exécutée.
  • La règle d'or de la journalisation est que vos journaux ne peuvent pas inutilement pousser d'autres journaux hors de la mémoire tampon, tout comme d'autres ne peuvent pas sortir les vôtres.

Règles de style Javatests

Suivez les conventions de dénomination des méthodes de test et utilisez un trait de soulignement pour séparer ce qui est testé du cas spécifique testé. Ce style permet de voir plus facilement quels cas sont testés. Par exemple:

testMethod_specificCase1 testMethod_specificCase2

void testIsDistinguishable_protanopia() {
    ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA)
    assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK))
    assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))
}