2012-06-05 15 views
38

Me gustaría tener cadenas de Java constantes en un lugar y usarlas en todo el proyecto (muchas clases).¿Compartir cadenas constantes en Java en muchas clases?

¿Cuál es la forma recomendada de lograr esto?

+0

¿qué pasa con una clase estática con métodos estáticos que devuelven cadenas constantes? –

+3

Este no es un método de diseño recomendado para Java. Pon tus constantes en las clases donde son relevantes. – beerbajay

+0

@beerbajay Pero necesito esas cuerdas en algunas clases, ¿cuál es la forma recomendada de hacerlo? – Danijel

Respuesta

42
public static final String CONSTANT_STRING="CONSTANT_STRING"; 

constantes deben ser:

  1. pública - de modo que se puede acceder desde cualquier lugar
  2. estática - no hay necesidad de crear una instancia
  3. final - dado que no se debe permitir que sus constantes cambien
  4. Según el convenio de nomenclatura de Java, debe estar en mayúscula para que sea fácil de leer y se destaque en la documentación de Java.

Hay instancias donde las interfaces se usan solo para mantener constantes aunque no veo ninguna razón para hacerlo y también se considera una mala práctica crear una interfaz para mantener constantes, otro enfoque es mantenerlo la clase donde tiene más sentido.

por ej.

JFrame tiene EXIT_ON_CLOSE contant, cualquier clase que subclases JFrame tendrá acceso a ella y también tiene sentido tener en JFrame y no en JComponent ya que no todos los componentes tendrán la opción de ser cerrado.

+8

+1 para una buena respuesta. Aunque el uso de una interfaz para este fin se considera mala práctica, se debe mencionar –

+1

@Jimmy: ¿por qué utilizar interfaces es una mala práctica? – WickeD

+4

interfaces se contraen usándolos solo para mantener constantes no tiene sentido – mprabhat

15

Debe crear una clase de las constantes que almacene todas las constantes.

como ProjectNameConstants.java

que contiene toda la cadena constante estática como se puede acceder a él a través del nombre de la clase.

p. Ej.

classname : MyAppConstants.java 

public static final String MY_CONST="my const string val"; 

puede acceder a él como

MyAppConstants.MY_CONST 
+2

, o bien eso o lo define como una "Cadena final pública estática" en el objeto que es responsable de esta cadena –

+0

¿por qué haría esto? Mi instinto me dice que esta es una idea terrible, pero estoy feliz de que se demuestre lo contrario. – Bruno

+0

@Bruno Es mejor idea mantener todas las constantes relacionadas en el mismo archivo. como todas las constantes de consultas sql relacionadas con un módulo deberían estar en una constante java como esa. –

0

Crear una class pública y para cada cadena constante cree un campo como éste

public static final String variableName = "string value";

3
public class SomeClass { 
    public static final String MY_CONST = "Some Value"; 
} 

Si se supone que es una clase constantes puros luego hacer el constructor privado.

public class Constants { 
    public static final String CONST_1 = "Value 1"; 
    public static final int CONST_2 = 754; 

    private Constants() { 
    } 
} 

Entonces no será posible instanciar esta clase.

+0

Es mejor simplemente hacerlo 'estático', no debería usar este enfoque de" constructor privado "cuando hay mejores opciones integradas en Java. –

+0

@Ryuji Estás totalmente equivocado y lo estás mezclando con C#. Eche un vistazo aquí, por ejemplo: http://stackoverflow.com/a/7486111/1350762 – maba

1

Debe dividir sus constantes en grupos a los que pertenecen, como dónde se usarán más, y definirlos como finales públicos estáticos en esas clases. A medida que avanza, puede parecer apropiado tener interfaces que definan sus constantes, pero resista el impulso de crear una interfaz monolítica que contenga todas las constantes. Simplemente no es un buen diseño.

2

Cree una clase llamada Constants en la base de su paquete principal (es decir, com.su compañía) con todas sus constantes allí. También hacen que el constructor privado para que ningún objeto se crea a partir de esta clase:

public class Constants { 

    private Constants() { 
     // No need to create Constants objects 
    } 

    public static final String CONSTANT_ONE = "VALUE_CONSTANT_ONE"; 
    public static final String CONSTANT_TWO = "VALUE_CONSTANT_TWO"; 
} 
6

La mejor práctica es utilizar Java Enum (After Java 5)

problemas con el enfoque de clase:

  1. No Typesafe
  2. Sin espacio de nombres
  3. Fragilidad

Compruebe los documentos de Java.

public enum Constants { 

    CONSTANT_STRING1("CONSTANT_VALUE1"), 
    CONSTANT_STRING2("CONSTANT_VALUE2"), 
    CONSTANT_STRING3("CONSTANT_VALUE3"); 

    private String constants; 

    private Constants(String cons) { 
     this.constants = cons; 
    } 
} 

Las enumeraciones se pueden utilizar como constantes.

Editar: Puede llamar a este Constants.CONSTANT_STRING1

+0

Esos problemas (tipo seguro, espacio de nombres y fragilidad) ocurrieron con el antiguo enfoque ** Enum ** (como un patrón, anterior a Java 5) . Ver ['enums' en JavaDoc] (http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html) –

+3

La forma de llamarlo no es' Constants.CONSTANT_STRING1 ', ya que devuelve algo del tipo' Constantes'. Tendría que llamarlo 'Constants.CONSTANT_STRING1.toString()' o 'Constants.CONSTANT_STRING1.name()'. –

+0

Como J.A.I.L. comentado, su ejemplo de código actual no * funciona *. Su llamada devuelve un objeto de tipo 'Constantes' en lugar de' Cadena' como se desea en la Pregunta. –

14

Como @mprabhat contestado antes, deben ser constantes public, static, final, y escrito en letras mayúsculas.

agrupándolos en una clase le ayuda a:

  1. No necesita saber todas las constantes que tiene. Muchos IDEs (como Eclipse) le muestran la lista de todos los campos que tiene una clase. Por lo tanto, solo presione CTRL+SPACE y obtenga una pista de las constantes que puede usar.

  2. Haciéndolos seguros en tiempo de compilación. Si usó String s, puede escribir con error "DATABASE_EXCEPTION" con "DATABSE_EXSCEPTION", y solo notará durante la ejecución (si tiene suerte y no lo nota en absoluto). También puede aprovechar la autocompletación.

  3. Lo ayuda a ahorrar memoria durante la ejecución. Solo necesitarás memoria para 1 instancia de la constante. I.E: (un ejemplo real) Si tiene String "DATABASE_EXCEPTION" 1000 veces en diferentes clases en su código, cada una de ellas tendrá una instancia diferente en la memoria.

Algunas otras consideraciones que pueda tener:

  1. añadir comentarios Javadoc, así que los programadores que utilizan las constantes pueden tener más información semántica de la constante. Se muestra como información sobre herramientas cuando presiona CTRL+SPACE. I.E:

    /** Indicates an exception during data retrieving, not during connection. */ 
    public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION"; 
    /** Indicates an exception during the connection to a database. */ 
    public static final String DATABASE_CONNECTION_EXCEPTION =" DATABASE_CONNECTION_EXCEPTION"; 
    
  2. Agregue semántica al identificador de la constante. Si tiene la constante "Y", y en ocasiones significa y otras veces año, considere el uso de 2 constantes diferentes.

    public static final String Y = "Y"; // Bad 
    public static final String YEAR = "Y"; 
    public static final String YES = "Y"; 
    

    Le ayudará si, en el futuro, decide cambiar los valores de las constantes.

    /** Year symbol, used for date formatters. */ 
    public static final String YEAR = "A"; // Year is Año, in Spanish. 
    public static final String YES = "S"; // Yes is Sí, in Spanish. 
    
  3. Usted puede no saber el valor de sus constantes hasta el tiempo de ejecución. IE: puedes leerlos desde los archivos de configuración.

    public class Constants 
    { 
        /** Message to be shown to the user if there's any SQL query problem. */ 
        public static final String DATABASE_EXCEPTION_MESSAGE; // Made with the 2 following ones. 
        public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION"; 
        public static final String MESSAGE = "MESSAGE"; 
    
        static { 
        DATABASE_EXCEPTION_MESSAGE = DATABASE_EXCEPTION + MESSAGE; // It will be executed only once, during the class's [first] instantiation. 
        } 
    

    }

  4. Si su clase constantes es demasiado grande, o se presuma que va a crecer demasiado en el futuro, se puede dividir en diferentes clases para los diferentes significados (de nuevo, semántica): ConstantDB, ConstantNetwork, etc.

inconvenientes:

  1. Todos los miembros de su equipo tienen que usar la (s) misma (s) clase (s) y la misma nomenclatura para las constantes. En un proyecto grande que no sería extraño encontrar 2 definiciones:

    public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION"; 
    public static final String EXCEPTION_DATABASE = "DATABASE_EXCEPTION"; 
    

    separados varios cientos de líneas o en diferentes clases constantes. O peor aún:

    /** Indicates an exception during data retrieving, not during connection. */ 
    public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION"; 
    /** Indicates an exception during data retrieving, not during connection. */ 
    public static final String EXCEPTION_DATABASE = "EXCEPTION_DATABASE"; 
    

    identificadores diferentes, para diferentes valores, que tienen el mismo significado (y utilizados para los mismos fines).

  2. Podría empeorar la legibilidad. Tener que escribir más por hacer lo mismo:

    if ("Y".equals(getOptionSelected()) { 
    

    vs

    if (ConstantsWebForm.YES.equals(getOptionSeleted()) { 
    
  3. ¿Cómo debe ser pedida constantes en la clase? ¿Alfabéticamente? Todas las constantes relacionadas juntas? ¿Para que se creen/necesiten? ¿Quién debería ser responsable de que el orden sea correcto? Cualquier reordenamiento (suficientemente grande) de las constantes sería visto como un desastre en un sistema de control de versiones.

Bueno, ha tomado más de lo que esperaba. Cualquier ayuda/crítica es/son bienvenidos.

+0

Excelente publicación, gracias. – Danijel

+0

Gracias por el apoyo. –

+0

¡Gracias por más detalles! +1 –

0
public enum Constants { 

CONSTANT_STRING1("CONSTANT_VALUE1"), 
CONSTANT_STRING2("CONSTANT_VALUE2"), 
CONSTANT_STRING3("CONSTANT_VALUE3"); 

private String constants; 

private Constants(String cons) { 
    this.constants = cons; 
} 
    @JsonValue 
@Override 
public String toString() { 
    return constants; 
} 

}

Utilícelo Constants.CONSTANT_STRING1.toString()

Cuestiones relacionadas