2011-04-12 11 views
48
public enum MyUnits 
{ 
    MILLSECONDS(1, "milliseconds"), SECONDS(2, "seconds"),MINUTES(3,"minutes"), HOURS(4, "hours"); 

    private MyUnits(int quantity, String units) 
    { 
     this.quantity = quantity; 
     this.units = units; 
    } 

    private int quantity; 
    private String units; 

public String toString() 
{ 
    return (quantity + " " + units); 
} 

public static void main(String[] args) 
{ 
    for (MyUnits m : MyUnits.values()) 
    { 
     System.out.println(m.MILLSECONDS); 
     System.out.println(m.SECONDS); 
     System.out.println(m.MINUTES); 
     System.out.println(m.HOURS); 
    } 
} 
} 

Esto se refiere a post .. no fue capaz de responder o comentar ninguno así que creó uno nuevo. ¿Por qué mis¿Por qué se debe acceder al campo estático de forma estática?

System.out.println(m.MILLSECONDS); 

advertencias-La entrega MyUnits.MILLSECONDS campo estático se debería acceder de una manera estática? Gracias.

+7

Cambié el título, que era "Java Code Optimization". Por favor, tenga más cuidado con el título de la pregunta. –

+0

ya mi mal, se ocupará de la próxima vez :) – Ava

Respuesta

84

Porque cuando accede a un campo estático, debe hacerlo en la clase (o en este caso la enumeración). Al igual que en

MyUnits.MILLISECONDS; 
No

en una instancia como en

m.MILLISECONDS; 

Editar Para abordar la cuestión de qué: En Java, cuando se declara algo tan static, que está diciendo que es un miembro de la clase, no el objeto (de ahí por qué hay solo uno). Por lo tanto, no tiene sentido acceder al objeto, porque ese miembro de datos en particular está asociado a la clase.

+0

¡Muchas gracias! Lo tengo. – Ava

+7

Sí ... pero * ¿POR QUÉ * se debe acceder al campo estático de forma estática? – dokaspar

+0

@Dominik echa un vistazo a mis ediciones arriba –

10

Porque ... (MILLISECONDS) es un campo estático (escondido en una enumeración, pero eso es lo que es) ... sin embargo, se invoca a un ejemplo del tipo dado (pero véase más adelante como esto no es realmente verdadero).

javac lo "aceptará", pero en realidad debería ser MyUnits.MILLISECONDS (o sin prefijo en el ámbito correspondiente).

En realidad, javac "reescribe" el código de la forma preferida - si m pasó a ser null no sería lanzar una NPE en tiempo de ejecución - que de hecho nunca se invoca en el ejemplo).

Happy coding.


No estoy realmente ver cómo el título de la pregunta encaja con el resto :-) títulos más precisos y especializados aumentan la pregunta también la probabilidad/respuestas pueden beneficiar a otros programadores.

48

De hecho, hay una buena razón:
El acceso no estática no siempre funciona, por razones de ambigüedad.

Supongamos que tenemos dos clases, A y B, siendo esta última una subclase de A, con campos estáticos con el mismo nombre:

public class A { 
    public static String VALUE = "Aaa"; 
} 

public class B extends A { 
    public static String VALUE = "Bbb"; 
} 

Acceso directo a la variable estática:

A.VALUE (="Aaa") 
B.VALUE (="Bbb") 

acceso indirecto utilizando una instancia (un compilador da aviso de que el valor se debe tener acceso de forma estática):

new B().VALUE (="Bbb") 

Hasta ahora, tan bueno, el compilador puede adivinar qué variable estática usar, la que está en la superclase está de alguna manera más lejos, parece de alguna manera lógica.

Ahora al punto en que se pone complicado: las interfaces también pueden tener variables estáticas.

public interface C { 
    public static String VALUE = "Ccc"; 
} 

public interface D { 
    public static String VALUE = "Ddd"; 
} 

Vamos a quitar la variable estática de B, y observar las situaciones siguientes:

  • B implements C, D
  • B extends A implements C
  • B extends A implements C, D
  • B extends A implements C donde A implements D
  • B extends A implements C donde C extends D
  • ...

La declaración new B().VALUE es ahora ambigua, como el compilador no puede decidir qué variable estática estaba destinado. Y esa es exactamente la razón por la cual se debe acceder a las variables estáticas de una manera estática.

+8

Esta debería ser la respuesta correcta OMI, muestra por qué es peligroso. – Water

+3

La respuesta de @ChrisThompson al "por qué" fue simplemente "no tiene sentido, usted lo declaró estático, por lo tanto, úselo como estático" - ESTA respuesta en realidad da justificación para * por qué * es una mala práctica que vale la pena mala consecuencia – mmcrae

+3

Acepto que esta respuesta es mucho más útil que la aceptada. ¡Así que no siempre funciona como debería! Aún así es genial. Finalmente, supongo que una pregunta interesante posterior es: ¿por qué es posible acceder a campos o métodos estáticos desde las instancias en primer lugar? – Dici

Cuestiones relacionadas