Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Estilo de código Java AOSP para colaboradores

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

Los estilos de código en esta página son reglas estrictas para contribuir con código Java al Proyecto de código abierto de Android (AOSP). Por lo general , no se aceptan contribuciones a la plataforma Android que no cumplan con estas reglas. Reconocemos que no todo el código existente sigue estas reglas, pero esperamos que todo el código nuevo las cumpla. Consulte Codificación con respeto para ver ejemplos de terminología a usar y evitar para un ecosistema más inclusivo.

Se consistente

Una de las reglas más simples es SER CONSISTENTE. Si está editando código, tómese unos minutos para mirar el código circundante y determinar su estilo. Si ese código usa espacios alrededor de las cláusulas if , tú también deberías hacerlo. Si los comentarios del código tienen pequeños cuadros de estrellas alrededor, haga que sus comentarios también tengan pequeños cuadros de estrellas alrededor.

El objetivo de tener pautas de estilo es tener un vocabulario común de codificación, para que los lectores puedan concentrarse en lo que dices, en lugar de cómo lo dices. Presentamos reglas de estilo global aquí para que conozca el vocabulario, pero el estilo local también es importante. Si el código que agrega a un archivo se ve drásticamente diferente del código existente a su alrededor, los lectores pierden el ritmo cuando lo leen. Trate de evitar esto.

Reglas del lenguaje Java

Android sigue las convenciones de codificación estándar de Java con las reglas adicionales que se describen a continuación.

No ignore las excepciones

Puede ser tentador escribir código que ignore una excepción, como:

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

No hagas esto. Si bien puede pensar que su código nunca encontrará esta condición de error o que no es importante manejarlo, ignorar este tipo de excepción crea minas en su código para que otra persona las active algún día. Debe manejar cada excepción en su código de una manera basada en principios; el manejo específico varía según el caso.

" Cada vez que alguien tiene una cláusula de captura vacía, debe tener una sensación espeluznante. Definitivamente, hay momentos en los que en realidad es lo correcto, pero al menos tienes que pensar en ello. En Java no puedes escapar de la sensación espeluznante. " -James Gosling

Las alternativas aceptables (en orden de preferencia) son:

  • Lanza la excepción a la persona que llama a tu método.
      void setServerPort(String value) throws NumberFormatException {
          serverPort = Integer.parseInt(value);
      }
    
  • Lance una nueva excepción que sea apropiada para su nivel de abstracción.
      void setServerPort(String value) throws ConfigurationException {
        try {
            serverPort = Integer.parseInt(value);
        } catch (NumberFormatException e) {
            throw new ConfigurationException("Port " + value + " is not valid.");
        }
      }
    
  • Maneje el error con gracia y sustituya un valor apropiado en el bloque catch {} .
      /** 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
        }
      }
    
  • Captura la excepción y lanza una nueva instancia de RuntimeException . Esto es peligroso, así que hágalo solo si está seguro de que si ocurre este error, lo apropiado es bloquear.
      /** 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);
        }
      }
    
  • Como último recurso, si está seguro de que ignorar la excepción es apropiado, puede ignorarla, pero también debe comentar por qué con una buena razón.
    /** 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.
        }
    }
    

No detecte excepciones genéricas

Puede ser tentador ser perezoso al detectar excepciones y hacer algo como esto:

  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!
  }

No hagas esto. En casi todos los casos, es inapropiado capturar Exception genérica o Throwable (preferiblemente no Throwable porque incluye excepciones de Error ). Es peligroso porque significa que las excepciones que nunca esperó (incluidas las excepciones en tiempo de ejecución como ClassCastException ) quedan atrapadas en el manejo de errores a nivel de la aplicación. Oculta las propiedades de manejo de fallas de su código, lo que significa que si alguien agrega un nuevo tipo de excepción en el código que está llamando, el compilador no señalará que necesita manejar el error de manera diferente. En la mayoría de los casos, no debería manejar diferentes tipos de excepciones de la misma manera.

La rara excepción a esta regla es el código de prueba y el código de nivel superior donde desea detectar todo tipo de errores (para evitar que aparezcan en una interfaz de usuario o para mantener un trabajo por lotes en ejecución). En estos casos, puede capturar una Exception genérica (o Throwable ) y manejar el error de manera adecuada. Sin embargo, piense detenidamente antes de hacer esto y escriba comentarios que expliquen por qué es seguro en este contexto.

Alternativas a la captura de excepciones genéricas:

  • Captura cada excepción por separado como parte de un bloque de captura múltiple, por ejemplo:
    try {
        ...
    } catch (ClassNotFoundException | NoSuchMethodException e) {
        ...
    }
  • Refactorice su código para tener un manejo de errores más detallado, con múltiples bloques de prueba. Separe el IO del análisis y maneje los errores por separado en cada caso.
  • Vuelva a lanzar la excepción. Muchas veces no necesita capturar la excepción en este nivel de todos modos, simplemente deje que el método la arroje.

¡Recuerda que las excepciones son tus amigas! Cuando el compilador se queje de que no está detectando una excepción, no frunce el ceño. ¡Sonreír! El compilador simplemente le facilitó la detección de problemas de tiempo de ejecución en su código.

No use finalizadores

Los finalizadores son una forma de ejecutar un fragmento de código cuando un objeto se recolecta como basura. Si bien los finalizadores pueden ser útiles para la limpieza (particularmente de recursos externos), no hay garantías de cuándo se llamará a un finalizador (o incluso de que se llamará en absoluto).

Android no utiliza finalizadores. En la mayoría de los casos, puede usar un buen manejo de excepciones en su lugar. Si necesita absolutamente un finalizador, defina un método close() (o similar) y documente exactamente cuándo se debe llamar a ese método (consulte InputStream para ver un ejemplo). En este caso, es apropiado, pero no obligatorio, imprimir un mensaje de registro corto del finalizador, siempre que no se espere que inunde los registros.

Importaciones totalmente calificadas

Cuando desee utilizar la Bar de clase del paquete foo , hay dos formas posibles de importarlo:

  • import foo.*;

    Reduce potencialmente el número de declaraciones de importación.

  • import foo.Bar;

    Hace que sea obvio qué clases se utilizan y el código es más legible para los mantenedores.

Utilice import foo.Bar; para importar todo el código de Android. Se hace una excepción explícita para las bibliotecas estándar de Java ( java.util.* , java.io.* , etc.) y el código de prueba de unidad ( junit.framework.* ).

Reglas de la biblioteca de Java

Existen convenciones para usar las bibliotecas y herramientas Java de Android. En algunos casos, la convención ha cambiado de manera importante y el código anterior puede usar un patrón o una biblioteca en desuso. Cuando se trabaja con dicho código, está bien continuar con el estilo existente. Sin embargo, al crear nuevos componentes, nunca use bibliotecas en desuso.

Reglas de estilo Java

Usar comentarios estándar de Javadoc

Cada archivo debe tener una declaración de derechos de autor en la parte superior, seguida de declaraciones de paquete e importación (cada bloque separado por una línea en blanco) y, finalmente, la declaración de clase o interfaz. En los comentarios de Javadoc, describa qué hace la clase o la interfaz.

/*
 * 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 {
    ...
}

Cada clase y método público no trivial que escriba debe contener un comentario de Javadoc con al menos una oración que describa lo que hace la clase o el método. Esta oración debe comenzar con un verbo descriptivo en tercera persona.

Ejemplos

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

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

o

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

No necesita escribir Javadoc para métodos triviales de obtención y configuración como setFoo() si todo lo que su Javadoc diría es "sets Foo". Si el método hace algo más complejo (como imponer una restricción o tiene un efecto secundario importante), debe documentarlo. Si no es obvio lo que significa la propiedad "Foo", debe documentarlo.

Cada método que escriba, público o no, se beneficiaría de Javadoc. Los métodos públicos son parte de una API y, por lo tanto, requieren Javadoc. Android no impone un estilo específico para escribir comentarios de Javadoc, pero debe seguir las instrucciones en Cómo escribir comentarios de documentos para la herramienta Javadoc .

Escribir métodos cortos

Cuando sea factible, mantenga los métodos pequeños y enfocados. Reconocemos que los métodos largos a veces son apropiados, por lo que no se impone un límite estricto a la longitud del método. Si un método supera las 40 líneas, piense si se puede dividir sin dañar la estructura del programa.

Definir campos en lugares estándar

Defina campos en la parte superior del archivo o inmediatamente antes de los métodos que los usan.

Limitar el alcance de la variable

Mantenga el alcance de las variables locales al mínimo. Esto aumenta la legibilidad y la capacidad de mantenimiento de su código y reduce la probabilidad de error. Declare cada variable en el bloque más interno que encierra todos los usos de la variable.

Declare las variables locales en el punto donde se utilizan por primera vez. Casi todas las declaraciones de variables locales deben contener un inicializador. Si aún no tiene suficiente información para inicializar una variable con sensatez, posponga la declaración hasta que la tenga.

La excepción son las sentencias try-catch. Si una variable se inicializa con el valor de retorno de un método que arroja una excepción verificada, debe inicializarse dentro de un bloque de prueba. Si el valor se debe usar fuera del bloque de prueba, entonces se debe declarar antes del bloque de prueba, donde aún no se puede inicializar con sensatez:

// 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));

Sin embargo, incluso puedes evitar este caso encapsulando el bloque try-catch en un método:

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));

Declare las variables de bucle en la declaración for misma a menos que haya una razón de peso para hacer lo contrario:

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

y

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

Ordenar extractos de importación

El orden de las declaraciones de importación es:

  1. Importaciones de Android
  2. Importaciones de terceros ( com , junit , net , org )
  3. java y javax

Para que coincida exactamente con la configuración del IDE, las importaciones deben ser:

  • Alfabético dentro de cada grupo, con letras mayúsculas antes de minúsculas (por ejemplo, Z antes de a)
  • Separados por una línea en blanco entre cada grupo principal ( android , com , junit , net , org , java , javax )

Originalmente, no había ningún requisito de estilo en el pedido, lo que significa que los IDE siempre cambiaban el pedido o los desarrolladores de IDE tenían que desactivar las funciones de administración de importación automática y mantener las importaciones manualmente. Esto se consideró malo. Cuando se preguntó sobre el estilo de Java, los estilos preferidos variaron enormemente y se redujo a que Android necesitaba simplemente "elegir un orden y ser coherente". Así que elegimos un estilo, actualizamos la guía de estilo e hicimos que los IDE lo obedecieran. Esperamos que a medida que los usuarios de IDE trabajen en el código, las importaciones en todos los paquetes coincidirán con este patrón sin un esfuerzo de ingeniería adicional.

Elegimos este estilo de tal manera que:

  • Las importaciones que la gente quiere ver primero tienden a estar en la parte superior ( android ).
  • Las importaciones que la gente quiere mirar al menos tienden a estar en la parte inferior ( java ).
  • Los humanos pueden seguir fácilmente el estilo.
  • Los IDE pueden seguir el estilo.

Ponga las importaciones estáticas por encima de todas las demás importaciones ordenadas de la misma manera que las importaciones regulares.

Usar espacios para la sangría

Usamos cuatro (4) sangrías de espacio para bloques y nunca tabulaciones. En caso de duda, sea consistente con el código circundante.

Usamos ocho (8) guiones de espacio para los ajustes de línea, incluidas las llamadas y asignaciones de funciones.

Recomendado

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

No recomendado

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

Siga las convenciones de nomenclatura de campos

  • Los nombres de campos no públicos y no estáticos comienzan con m .
  • Los nombres de campos estáticos comienzan con s .
  • Otros campos comienzan con una letra minúscula.
  • Los campos finales estáticos (constantes, profundamente inmutables) son ALL_CAPS_WITH_UNDERSCORES .

Por ejemplo:

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;
}

Usar estilo de llave estándar

Coloque llaves en la misma línea que el código anterior, no en su propia línea:

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

Requerimos llaves alrededor de las declaraciones para un condicional. Excepción: si todo el condicional (la condición y el cuerpo) caben en una sola línea, puedes (pero no estás obligado a hacerlo) ponerlo todo en una sola línea. Por ejemplo, esto es aceptable:

if (condition) {
    body();
}

y esto es aceptable:

if (condition) body();

pero esto no es aceptable:

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

Limitar la longitud de la línea

Cada línea de texto en su código debe tener como máximo 100 caracteres. Si bien se ha debatido mucho sobre esta regla, se mantiene la decisión de que 100 caracteres es el máximo con las siguientes excepciones :

  • Si una línea de comentario contiene un comando de ejemplo o una URL literal de más de 100 caracteres, esa línea puede tener más de 100 caracteres para facilitar la operación de cortar y pegar.
  • Las líneas de importación pueden superar el límite porque los humanos rara vez las ven (esto también simplifica la escritura de herramientas).

Usar anotaciones estándar de Java

Las anotaciones deben preceder a otros modificadores para el mismo elemento de idioma. Las anotaciones de marcador simple (por ejemplo, @Override ) se pueden enumerar en la misma línea con el elemento de idioma. Si hay varias anotaciones o anotaciones parametrizadas, enumérelas una por línea en orden alfabético.

Las prácticas estándar de Android para las tres anotaciones predefinidas en Java son:

  • Utilice la anotación @Deprecated siempre que se desaconseje el uso del elemento anotado. Si usa la anotación @Deprecated , también debe tener una etiqueta Javadoc @deprecated y debe nombrar una implementación alternativa. Además, recuerde que se supone que todavía funciona un método @Deprecated . Si ve un código antiguo que tiene una etiqueta @deprecated Javadoc, agregue la anotación @Deprecated .
  • Use la anotación @Override siempre que un método anule la declaración o implementación de una superclase. Por ejemplo, si usa la etiqueta Javadoc @inheritdocs y se deriva de una clase (no de una interfaz), también debe anotar que el método anula el método de la clase principal.
  • Utilice la anotación @SuppressWarnings solo en circunstancias en las que sea imposible eliminar una advertencia. Si una advertencia pasa esta prueba "imposible de eliminar", se debe usar la anotación @SuppressWarnings para garantizar que todas las advertencias reflejen problemas reales en el código.

    Cuando es necesaria una anotación @SuppressWarnings , debe ir precedida de un comentario TODO que explique la condición "imposible de eliminar". Esto normalmente identifica una clase infractora que tiene una interfaz incómoda. Por ejemplo:

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

    Cuando se requiere una anotación @SuppressWarnings , refactorice el código para aislar los elementos de software donde se aplica la anotación.

Tratar los acrónimos como palabras

Trate los acrónimos y abreviaturas como palabras al nombrar variables, métodos y clases para que los nombres sean más legibles:

Bueno Malo
Solicitud XmlHttp Solicitud XMLHTTP
getCustomerId obtener ID de cliente
clase html clase HTML
URL de cadena URL de cadena
identificación larga identificación larga

Como las bases de código de JDK y Android son inconsistentes en cuanto a los acrónimos, es prácticamente imposible ser coherente con el código circundante. Por lo tanto, trate siempre los acrónimos como palabras.

Usar comentarios TODO

Use comentarios TODO para el código que es temporal, una solución a corto plazo o lo suficientemente bueno pero no perfecto. Estos comentarios deben incluir la cadena TODO en mayúsculas, seguida de dos puntos:

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

y

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

Si su TODO tiene el formato "En una fecha futura, haga algo", asegúrese de incluir una fecha específica ("Reparar para noviembre de 2005") o un evento específico ("Elimine este código después de que todos los mezcladores de producción entiendan el protocolo V7". ).

Registrar con moderación

Si bien el registro es necesario, tiene un impacto negativo en el rendimiento y pierde su utilidad si no se mantiene razonablemente conciso. Las instalaciones de registro proporcionan cinco niveles diferentes de registro:

  • ERROR : se utiliza cuando ha ocurrido algo fatal, es decir, algo tendrá consecuencias visibles para el usuario y no se podrá recuperar sin eliminar algunos datos, desinstalar aplicaciones, borrar las particiones de datos o volver a actualizar todo el dispositivo (o algo peor). Este nivel siempre se registra. Los problemas que justifican algún registro en el nivel de ERROR son buenos candidatos para informar a un servidor de recopilación de estadísticas.
  • WARNING : use cuando suceda algo grave e inesperado, es decir, algo que tendrá consecuencias visibles para el usuario pero que probablemente se pueda recuperar sin pérdida de datos al realizar alguna acción explícita, que va desde esperar o reiniciar una aplicación hasta volver a descargarla una nueva versión de una aplicación o reiniciar el dispositivo. Este nivel siempre se registra. Los problemas que justifican el registro en el nivel de WARNING también se pueden considerar para informar a un servidor de recopilación de estadísticas.
  • INFORMATIVE : se usa para indicar que sucedió algo interesante, es decir, cuando se detecta una situación que probablemente tendrá un impacto generalizado, aunque no es necesariamente un error. Tal condición solo debe ser registrada por un módulo que crea que es el más autorizado en ese dominio (para evitar el registro duplicado por parte de componentes no autorizados). Este nivel siempre se registra.
  • DEBUG : se utiliza para observar con más detalle lo que sucede en el dispositivo que podría ser relevante para investigar y depurar comportamientos inesperados. Registre solo lo que se necesita para recopilar suficiente información sobre lo que sucede con su componente. Si sus registros de depuración dominan el registro, debe usar el registro detallado.

    Este nivel se registra incluso en las compilaciones de lanzamiento, y se requiere que esté rodeado por un if (LOCAL_LOG) o if LOCAL_LOGD) , donde LOCAL_LOG[D] se define en su clase o subcomponente, de modo que existe la posibilidad de deshabilitar todo ese registro . Por lo tanto, no debe haber lógica activa en un bloque if (LOCAL_LOG) . Toda la creación de cadenas para el registro también debe colocarse dentro del bloque if (LOCAL_LOG) . No refactorice la llamada de registro en una llamada de método si va a hacer que la construcción de cadenas se lleve a cabo fuera del bloque if (LOCAL_LOG) .

    Hay algún código que todavía dice if (localLOGV) . Esto también se considera aceptable, aunque el nombre no es estándar.

  • VERBOSE : se usa para todo lo demás. Este nivel solo se registra en compilaciones de depuración y debe estar rodeado por un bloque if (LOCAL_LOGV) (o equivalente) para que pueda compilarse de forma predeterminada. Cualquier construcción de cadena se elimina de las versiones de lanzamiento y debe aparecer dentro del bloque if (LOCAL_LOGV) .

notas

  • Dentro de un módulo dado, que no sea en el nivel VERBOSE , un error solo debe informarse una vez si es posible. Dentro de una sola cadena de llamadas de función dentro de un módulo, solo la función más interna debe devolver el error, y las personas que llaman en el mismo módulo solo deben agregar algo de registro si eso ayuda significativamente a aislar el problema.
  • En una cadena de módulos, excepto en el nivel VERBOSE , cuando un módulo de nivel inferior detecta datos no válidos provenientes de un módulo de nivel superior, el módulo de nivel inferior solo debe registrar esta situación en el registro DEBUG , y solo si el registro proporciona información que no está disponible de otro modo para la persona que llama. Específicamente, no es necesario registrar situaciones en las que se lanza una excepción (la excepción debe contener toda la información relevante), o donde la única información que se registra está contenida en un código de error. Esto es especialmente importante en la interacción entre el marco y las aplicaciones, y las condiciones causadas por aplicaciones de terceros que el marco maneja correctamente no deberían desencadenar un registro superior al nivel DEBUG . Las únicas situaciones que deberían activar el registro en el nivel INFORMATIVE o superior es cuando un módulo o aplicación detecta un error en su propio nivel o proveniente de un nivel inferior.
  • Cuando es probable que ocurra muchas veces una condición que normalmente justificaría algún registro, puede ser una buena idea implementar algún mecanismo de limitación de velocidad para evitar el desbordamiento de los registros con muchas copias duplicadas de la misma información (o muy similar).
  • Las pérdidas de conectividad de la red se consideran comunes y se esperan por completo, y no se deben registrar de forma gratuita. Una pérdida de conectividad de red que tenga consecuencias dentro de una aplicación debe registrarse en el nivel DEBUG o VERBOSE (dependiendo de si las consecuencias son lo suficientemente graves e inesperadas como para registrarse en una compilación de versión).
  • Tener un sistema de archivos completo en un sistema de archivos al que pueden acceder o en nombre de aplicaciones de terceros no debe registrarse en un nivel superior a INFORMATIVO.
  • Los datos no válidos que provienen de una fuente que no es de confianza (incluido cualquier archivo en el almacenamiento compartido o los datos que provienen de una conexión de red) se consideran esperados y no deberían desencadenar ningún registro en un nivel superior a DEBUG cuando se detecta que no es válido (e incluso entonces el registro debe ser lo más limitada posible).
  • Cuando se usa en objetos String , el operador + crea implícitamente una instancia de StringBuilder con el tamaño de búfer predeterminado (16 caracteres) y potencialmente otros objetos String temporales. Por lo tanto, crear explícitamente objetos StringBuilder no es más costoso que confiar en el operador predeterminado + (y puede ser mucho más eficiente). Tenga en cuenta que el código que llama a Log.v() se compila y ejecuta en versiones de lanzamiento, incluida la creación de cadenas, incluso si no se leen los registros.
  • Cualquier registro que esté destinado a ser leído por otras personas y que esté disponible en las compilaciones de lanzamiento debe ser conciso sin ser críptico, y debe ser comprensible. Esto incluye todos los registros hasta el nivel DEBUG .
  • Cuando sea posible, siga iniciando sesión en una sola línea. Se aceptan líneas de hasta 80 o 100 caracteres. Evite longitudes superiores a 130 o 160 caracteres (incluida la longitud de la etiqueta) si es posible.
  • Si los informes de registro son exitosos, nunca lo use en niveles superiores a VERBOSE .
  • Si está utilizando el registro temporal para diagnosticar un problema que es difícil de reproducir, manténgalo en el nivel DEBUG o VERBOSE y enciérrelo con bloques if que permitan desactivarlo en tiempo de compilación.
  • Tenga cuidado con las fugas de seguridad a través del registro. Evite registrar información privada. En particular, evite registrar información sobre contenido protegido. Esto es especialmente importante cuando se escribe código de marco, ya que no es fácil saber de antemano qué será y qué no será información privada o contenido protegido.
  • Nunca use System.out.println() (o printf() para código nativo). System.out y System.err se redireccionan a /dev/null , por lo que sus declaraciones de impresión no tienen efectos visibles. Sin embargo, toda la construcción de cadenas que ocurre para estas llamadas todavía se ejecuta.
  • La regla de oro del registro es que sus registros no pueden sacar innecesariamente otros registros del búfer, al igual que otros no pueden sacar los suyos.

Reglas de estilo de Javatests

Siga las convenciones de nomenclatura de los métodos de prueba y use un guión bajo para separar lo que se está probando del caso específico que se está probando. Este estilo facilita ver qué casos se están probando. Por ejemplo:

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))
}