web-dev-qa-db-fra.com

Pourquoi faut-il accéder au champ statique de manière statique?

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

Il s’agit de post ..n’est pas en mesure de répondre ou de commenter tout message ainsi créé. Pourquoi mes

System.out.println(m.MILLSECONDS);

donner des avertissements-Le champ statique MyUnits.MILLSECONDS doit être accédé de manière statique? Merci.

56
Ava

Parce que lorsque vous accédez à un champ statique, vous devriez le faire sur la classe (ou dans ce cas, l'énumération). Un péché

MyUnits.MILLISECONDS;

Pas sur une instance comme dans

m.MILLISECONDS;

Edit Pour aborder la question de pourquoi : En Java, lorsque vous déclarez quelque chose comme static, vous êtes en disant que c'est un membre de la classe, pas l'objet (d'où pourquoi il n'y en a qu'un). Par conséquent, il n’a pas de sens d’y accéder sur l’objet, car ce membre de données particulier est associé à la classe.

99
Chris Thompson

Il y a en fait une bonne raison:
L'accès non statique ne fonctionne pas toujours, pour des raisons d'ambiguïté.

Supposons que nous avons deux classes, A et B, la dernière étant une sous-classe de A, avec des champs statiques du même nom:

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

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

Accès direct à la variable statique:

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

Accès indirect utilisant une instance (donne un compilateur avertissant que l'accès à VALUE doit être effectué de manière statique):

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

Jusqu'ici, tout va bien, le compilateur peut deviner quelle variable statique utiliser, celle de la super-classe est en quelque sorte plus éloignée, semble en quelque sorte logique.

Maintenant, au point de compliquer les choses: les interfaces peuvent aussi avoir des variables statiques.

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

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

Supprimons la variable statique de B et observons les situations suivantes:

  • B implements C, D
  • B extends A implements C
  • B extends A implements C, D
  • B extends A implements CA implements D
  • B extends A implements CC extends D
  • ...

L'instruction new B().VALUE est maintenant ambiguë, car le le compilateur ne peut pas décider de la variable statique qui était censée être utilisée, et le signalera comme une erreur:

error: la référence à VALUE est ambiguë
Les deux variables VALUE in C et VALUE in D correspondent

Et c'est exactement la raison pour laquelle les variables statiques doivent être accessibles de manière statique.

61
Peter Walser

Parce que ... il (MILLISECONDS) est un champ statique (caché dans une énumération, mais c'est ce qu'il est) ... mais il est invoqué sur une instance de la donnée tapez (mais voir ci-dessous car ce n'est pas vraiment vrai1).

javac va "accepter" ça, mais ça devrait vraiment être MyUnits.MILLISECONDS (ou non préfixé dans la portée applicable).

1 En fait, javac "réécrit" le code dans sa forme préférée. Si m était null, il ne jetterait pas de NPE au moment de l'exécution - il n'est jamais réellement appelé sur l'instance. ).

Bonne codage.


Je ne vois pas vraiment comment le titre de la question cadre avec le reste :-) Des titres plus précis et spécialisés augmentent les chances que la question/les réponses puissent bénéficier aux autres programmeurs.

10
user166390