2010-05-19 4 views
2
Public class Example { 

    private int number; 

    public Example(int number){ 
     this.number = number; 
    } 

    public int getNumber(){ 
     return number; 
    } 

    public void setNumber(int number){ 
     this.number = number; 
    } 

    public static void main(String[] args){ 
     Example e = new Example(5); 

Ce qui est préferé lors de l'accès à une variable dans sa propre classe; "e.number" ou "e.getNumber()"?Convention de langage Java; getters/setters

Modifier:
Je pense que la question la plus importante est: le compilateur connaît la méthode que vous appelez est un getter ou setter. Donc, e.setNumber(5); sera aussi rapide que e.number = 5;

+1

Pourquoi diable serait-ce la question importante? Le titre indique clairement que la question concerne une convention. – aioobe

Répondre

3

Je dirais que cela dépend de la situation. Si le champ est quelque chose de simple comme un int et peu susceptible de changer dans le futur, je voudrais y accéder en utilisant number et non getNumber().

Si le champ représente quelque chose de plus impliqué qui pourrait dans une situation peut-être calculée en situation future ou peut-être redéfinies dans une sous-classe, getNumber() est le choix évident.

Ma règle générale: S'il y a une chance à distance que je peux profiter de passer par getNumber() J'utilise getNumber(), sinon j'utilise number pour plus de clarté et de concision.

4

e.getNumber() est l'approche courante. Ainsi, get ou set + VariableName.

Vous pouvez également jeter un oeil HERE.

+2

Ceci est également la convention de codage Java suggérée par Sun. –

+1

@Chris, veillez à fournir une URL pour cela? – aioobe

+3

Pouvez-vous pointer le paragraphe exact? La question est autour de "sa propre classe". –

0

Numéro

sauf le nombre est membre privé d'une classe de base. Ensuite, j'utilise le getter/setter pour clarifier, ce n'est pas un membre de la classe qui s'étend.

Editer: Oh vous l'utilisez dans la fonction principale à l'intérieur de la classe? Puis ofc e.getNumber() comme l'autre gars a dit.

+0

Eh bien, vous ne pouvez pas accéder aux membres privés dans les sous- – aioobe

+0

Oui c'est pourquoi il est protégé;.) – InsertNickHere

3
this.number 

Dans la plupart des cas, ils seront optimisés pour le même code mais le point d'utiliser setters/getters est d'éviter API Changin en cas de changement de mise en œuvre. Cependant en classe vous n'utilisez pas "API" mais vous voyez tous les internes et l'état.

plus, vous pouvez utiliser

numer += 5; 

au lieu de

setNumber(getNumber() + 5); 

Modifier: Bien sûr en dehors de la classe, il shoudl être protégé par getter/setter que vous pouvez changer la représentation interne et vous pouvez fournir rétrocompatibilité en les réimplantant en termes de nouvelle représentation d'état.

Modifier 2: main est un peu spécial. Je dirais que main devrait être aussi minimal que possible - créer des objets et appeler une ou deux méthodes maximum - donc il ne devrait pas affecter de variables et devrait être traité comme une partie 'externe'. D'un autre côté, certains fournissent des méthodes de test dans main qui peuvent nécessiter un accès direct à l'état. Donc, si vous le pouvez, vous ne devriez pas accéder directement aux champs main.

En ce qui concerne la vitesse dans main, cela n'a pas d'importance, car le démarrage de la machine virtuelle Java compenserait les coûts. La vraie différence serait dans les boucles internes dans lesquelles JIT s'en occuperait.

0

nombre s'il est utilisé dans la même classe. Et e.getnumber dans toutes les sous-classes ou n'importe où à l'extérieur

+1

je dirais que « nombre » si elle est _only_ utilisé dans la même classe, e.getNumber autrement. –

+0

* Attention: les méthodes * sont virtuelles en Java. Si vous utilisez 'number' dans la même classe et surchargez' getNumber', vous ne bénéficierez pas de la spécialisation dans une implémentation de sous-classe possible. – aioobe

0

Si l'accesseur public existe à d'autres fins, il est préférable d'utiliser cet accesseur, car vous garantirez un accès cohérent à votre variable. Toutefois, si votre variable n'a pas d'accesseur public, il est considéré comme acceptable d'accéder directement à la variable. J'ai tendance à restreindre cela aux variables privées (c'est-à-dire pas d'accesseurs privés dans le code, mais les accesseurs protégés au lieu des membres protégés si vous avez besoin d'un accès dans une implémentation de la classe de base). Donc, pour résumer: Je garderais toujours les membres privés et j'accéderais à eux par des accesseurs, sauf si les seuls accesseurs nécessaires sont privés.

1

Il y aura seulement une différence si le getter/setter fait quelque chose en plus. Si vous savez dès le début ce sera le cas, utilisez les méthodes même dans la classe. Si ce n'est pas le cas, j'utiliserais la manipulation directe sur le terrain et je comptais sur Eclipse pour m'aider à refacturer plus tard si nécessaire.

0

Je préfère généralement passer par les setters/getters, même en accédant à la classe en interne. Je fais ceci parce qu'il peut y avoir des fois que je veux modifier les getters de sorte qu'il fasse plus que simplement récupérer une propriété (par exemple, la variable de charge paresseuse), et je veux avoir la flexibilité de pouvoir faire cela sans avoir à vous soucier de modifier d'autres parties de la classe. Cela dit, il y a des exceptions, bien qu'il s'agisse pour la plupart d'une préférence personnelle plutôt que d'une meilleure pratique générale. Je vais accéder à des variables membres directement:

  1. Lorsque la mise en œuvre de ce que je considère la fonctionnalité « bas niveau » (et ceux-ci sont tout à fait subjective, dans mon cas, je considère #equals(), #hashCode(), #toString() et le « bas niveau » comme) . Je ne pense pas qu'il y ait une très forte raison technique à cela, ça me semble "meilleur".
  2. S'il est trop incommode d'utiliser les setters/getters (par exemple, num ++ vs setNumber(getNumber() + 1) comme quelqu'un d'autre l'a fait remarquer).
  3. Si mon getter effectue un travail supplémentaire, et dans mon cas particulier, ne veut pas vouloir ce comportement.
  4. ... Et il y a probablement d'autres cas, j'ai raté ...
0

dire au revoir à multithreading avec this.number = .. sans parler de nécessité éventuelle de mettre en œuvre le contrôle de ce qui peut être à l'intérieur de cette .nombre. Avec setNumber() Java conclut que cette méthode pourrait être finale et peut faire beaucoup avec l'optimisation de sorte que vous ne pouvez pas sentir la différence ...

0

Les getters/setters sont gentils en ce qu'ils font souvent un peu plus que l'interface à un domaine privé.La valeur renvoyée/définie peut faire partie d'un calcul plus complexe qui se déroule dans les coulisses. Le danger cependant, c'est que parce qu'ils sont des appels de méthode à part entière, ils peuvent littéralement faire n'importe quoi - démarrer un processus, télécharger un fichier, faire une tâche coûteuse, etc. Ceci est bien sûr stupide du contexte d'un getter/setter mais est quelque chose à éviter. J'ai aussi entendu parler du code qui exécute la plupart de ce qu'il est censé faire chez les getters/setters, n'ayant pas de vraies méthodes !!

1

Pour répondre à votre dernière question, regardez cet exemple,

code Java:

public void test2() { 
    setNumber(getNumber() + 1); 
} 

Code Byte:

public test2()V 
    L0 
    LINENUMBER 47 L0 
    ALOAD 0 
    ALOAD 0 
    INVOKEVIRTUAL com/test/ByteCodeTester.getNumber()I 
    ICONST_1 
    IADD 
    INVOKEVIRTUAL com/test/ByteCodeTester.setNumber(I)V 
    L1 
    LINENUMBER 48 L1 
    RETURN 
    L2 
    LOCALVARIABLE this Lcom/test/ByteCodeTester; L0 L2 0 
    MAXSTACK = 3 
    MAXLOCALS = 1 

Comme vous pouvez le voir, le bytecode fait encore 2 appels de méthode. Donc le compilateur ne le traite pas différemment dans ce cas.

+1

Le bytecode n'est évidemment pas exécuté sur le matériel. Le bytecode diffère rarement beaucoup du code java. L'optimisation est faite par le jit, et dans ce cas, l'optimisation est une tâche triviale. – aioobe

0

La machine virtuelle Java optimisera loin l'appel de méthode du poseur chaque fois qu'il est sûr de le faire (par exemple dans presque tous les cas où vous seriez tenté d'utiliser simplement le champ). Donc, pour la performance, cela ne devrait pas avoir d'importance sauf si vous utilisez une JVM qui ne fait pas de compilation JIT (par exemple Dalvik). En fait, vous pouvez enchaîner les appels de méthode à plusieurs niveaux et la JVM l'optimisera jusqu'à un accès au champ lorsqu'elle l'exécute sur le matériel.

donc vous besoin de vous inquiétez généralement pas sur les coûts de performance associés à getters/setters à moins qu'ils font vraiment quelque chose en plus (qui, ici, ils ne sont pas). Vous pouvez plutôt prendre la décision fondée sur d'autres critères (voulez-vous la possibilité de changer la représentation sous-jacente? Voulez-vous redéfinir dans les classes plus tard, et si oui, est le setter/getter redéfini correcte, ou est l'accès au champ approprié ? etc.).

Questions connexes