2008-09-16 11 views
51

Donc, je me suis volontairement gardé un Java n00b jusqu'à récemment, et ma première vraie exposition a provoqué un choc mineur: Java n'a pas de propriétés de style C#!(no) Propriétés à Java?

Ok, je peux vivre avec ça. Cependant, je peux également jurer que j'ai vu le code de getter/setter de propriété dans Java dans une base de code, mais je ne me souviens pas où. Comment cela a-t-il été réalisé? Y a-t-il une extension de la langue pour cela? Est-ce lié à NetBeans ou à quelque chose?

Répondre

59

Il existe un modèle "standard" pour les getters et setters en Java, appelé Bean properties. Fondamentalement toute méthode commençant par get, ne prenant aucun argument et renvoyant une valeur, est une propriété getter pour une propriété nommée comme le reste du nom de la méthode (avec une lettre de début en minuscule). De même, set crée un setter d'une méthode void avec un seul argument.

Par exemple:

// Getter for "awesomeString" 
public String getAwesomeString() { 
    return awesomeString; 
} 

// Setter for "awesomeString" 
public void setAwesomeString(String awesomeString) { 
    this.awesomeString = awesomeString; 
} 

La plupart Java IDEs va générer ces méthodes pour vous si vous leur demandez (dans Eclipse, il est aussi simple que de déplacer le curseur sur un champ et en appuyant sur Ctrl-1, puis en sélectionnant l'option de la liste).

Pour ce que ça vaut, pour une meilleure lisibilité, vous pouvez réellement utiliser is et has en place de get pour les propriétés de type booléen aussi, comme dans:

public boolean isAwesome(); 

public boolean hasAwesomeStuff(); 
+0

Je te jure que je l'ai vu la syntaxe de la propriété de style C# quelque part dans un code Java, mais pour la vie de moi je ne me souviens pas où et comment. Cela ne répond pas vraiment à ma question mais je l'accepterai pour le facteur génial. Peut-être que j'ai halluciné à l'époque. – Ishmaeel

+0

Je suis assez sûr que cela ne peut pas être fait en Java, désolé. Il y a beaucoup de langages JVM qui ont un support de première classe pour ce genre de chose, cependant, c'est peut-être ce que vous avez vu? – Calum

+0

Est-ce une violation de cette convention si vous préfixez une variable membre avec quelque chose comme 'm',' m_', ou '_', mais vous n'incluez pas ce préfixe dans le nom de la propriété? – Panzercrisis

2

Mon expérience Java n'est pas très élevée non plus, donc tout le monde se sent libre de me corriger. Mais autant que je sache, la convention générale est d'écrire deux méthodes comme ceci:

public string getMyString() { 
    // return it here 
} 

public void setMyString(string myString) { 
    // set it here 
} 
1

Si vous utilisez Eclipse il a la capacité de générer automatiquement le getter et la méthode setter pour les attributs internes, il peut être un utile et outil de gain de temps.

5

La convention de haricot est d'écrire du code comme ceci:

private int foo; 
public int getFoo() { 
    return foo; 
} 
public void setFoo(int newFoo) { 
    foo = newFoo; 
} 

Dans certains des autres langues sur la machine virtuelle Java, par exemple, Groovy, vous obtenez des propriétés Overridable semblables à C#, par exemple,

int foo 

qui est accessible avec un .foo simple et exploite les implémentations par défaut getFoo et setFoo que vous pouvez remplacer si nécessaire.

3

La plupart des IDEs Java génère automatiquement getter et le code setter pour vous si vous le voulez. Il existe un certain nombre de conventions différentes, et un EDI comme Eclipse vous permettra de choisir celui que vous souhaitez utiliser, et même de définir le vôtre. Eclipse inclut même le refactoring automatisé qui vous permettra d'envelopper une propriété dans un getter et un setter et modifiera tout le code qui accède à la propriété directement, pour l'utiliser avec le getter et/ou le setter. Bien sûr, Eclipse ne peut modifier que le code dont il a connaissance - toutes les dépendances externes que vous pourriez avoir pourraient être brisées par un tel refactoring.

1

Je ne fais que publier des annotations Java 5/6 et un processeur d'annotation pour l'aider.

Découvrez http://code.google.com/p/javadude/wiki/Annotations

La documentation est un peu léger en ce moment, mais le quickref devrait faire passer l'idée.

Fondamentalement, il génère une super-classe avec les getters/setters (et de nombreuses autres options de génération de code).

Une classe d'échantillon pourrait ressembler à

@Bean(properties = { 
    @Property(name="name", bound=true), 
    @Property(name="age,type=int.class) 
}) 
public class Person extends PersonGen { 
} 

Il y a beaucoup d'autres échantillons disponibles, et il n'y a pas de dépendances d'exécution dans le code généré. Envoyez-moi un e-mail si vous l'essayez et le trouvez utile! - Scott

6
public class Animal { 

    @Getter @Setter private String name; 
    @Getter @Setter private String gender; 
    @Getter @Setter private String species; 
} 

Cela ressemble à des propriétés C#. Il est http://projectlombok.org/

+1

Point à noter: cela compterait comme une extension de langue, et a tendance à rendre les EDI très confus. – millimoose

+2

@millimoose Vous avez juste besoin d'un plugin pour IDE. Malheureusement, tout le monde utilisant un tel code en a besoin. – dantuch

+2

"Vous avez besoin d'un plugin pour l'IDE" me donne envie de rouler un journal et écraser la personne responsable de celui-ci. (Bien que sans doute cela est plus dans les cas où la configuration IDE est le système de construction primaire pour une base de code.) – millimoose

29

Je suis surpris que personne n'a mentionné project lombok

Oui, actuellement il n'y a aucune propriété en java. Il y a aussi d'autres fonctionnalités manquantes.
Mais heureusement, nous avons project lombok qui essaie d'améliorer la situation. Il devient également de plus en plus populaire tous les jours.

Donc, si vous utilisez lombok:

@Getter @Setter int awesomeInteger = 5; 

Ce code va générer ainsi getAwesomeInteger et setAwesomeInteger. Donc, il est assez similaire à C# auto-implemented properties.

Vous pouvez obtenir plus d'informations sur getters et setters lombok here.
Vous devriez certainement vérifier other features ainsi. Mes favoris sont:

Lombok est bien intégré à IDEs, il va montrer les méthodes générées comme si elles existaient (suggestions, classe contenu, aller à la déclaration et refactoring).
Le seul problème avec lombok est que d'autres programmeurs pourraient ne pas le savoir. Vous pouvez toujours le code mais c'est plutôt une solution de contournement qu'une solution.

+3

ayant des méthodes que vous ne pouvez pas voir dans le code semble encore pire. Les auto-propriétés dans C# ne sont vraiment que la moitié de l'histoire - il s'agit surtout de nommer et de grouper la logique associée. –

+6

@JonnyLeeds bien, comment est-ce mal du tout? Vous pouvez les voir dans le code en repérant les annotations '' @ Getter'' et '' @ Setter'', et elles sont également affichées dans d'autres barres d'outils (comme des contours ou des suggestions) –

+0

Les annotations ne sont pas héritées faire du développement orienté objet. Si vous faites OO, alors vous savez qu'il y a très peu de raisons d'avoir même des getters et setters. Il est préférable d'exposer le comportement plutôt que le modèle de données. Nous sommes bien au-delà où n'importe qui devrait employer des structures (haricots). –

2

De Jeffrey Richter livre CLR via C#: (Je pense que ceux-ci pourraient être les raisons pour lesquelles les propriétés ne sont pas encore ajoutés en JAVA)

  • Méthode de propriété peut jeter une exception; l'accès au champ ne déclenche jamais d'exception.
  • Une propriété ne peut pas être transmise en tant que paramètre out ou ref à une méthode; un champ peut.
  • Une méthode de propriété peut prendre beaucoup de temps à s'exécuter; l'accès au champ se termine toujours immédiatement. Une raison courante d'utiliser les propriétés est d'effectuer une synchronisation de thread, qui peut arrêter le thread pour toujours, et par conséquent, une propriété ne doit pas être utilisée si la synchronisation de thread est requise. Dans cette situation, une méthode est préférée. En outre, si votre classe est accessible à distance (par exemple, votre classe est dérivée de System.MarshalByRefObject), l'appel de la méthode de propriété sera très lent, et par conséquent, une méthode est préférée à une propriété. À mon avis, les classes dérivées de MarshalByRefObject ne devraient jamais utiliser les propriétés.
  • Si elle est appelée plusieurs fois de suite, une méthode de propriété peut renvoyer une valeur différente chaque fois heure; un champ renvoie la même valeur à chaque fois. La classe System.DateTime a une propriété readonly Now qui renvoie la date et l'heure actuelles. Chaque fois que vous interrogez cette propriété , elle renvoie une valeur différente. C'est une erreur, et Microsoft souhaite que ils pourraient réparer la classe en faisant maintenant une méthode au lieu d'une propriété. La propriété Environment TickCount est un autre exemple de cette erreur.
  • Une méthode de propriété peut provoquer des effets secondaires observables; l'accès au terrain ne le fait jamais. Dans d'autres mots , un utilisateur d'un type devrait être en mesure de définir diverses propriétés définies par un type dans n'importe quel ordre qu'il ou elle choisit sans remarquer de comportement différent dans le type.
  • Une méthode de propriété peut nécessiter de la mémoire supplémentaire ou renvoyer une référence à quelque chose qui ne fait pas réellement partie de l'état de l'objet, de sorte que la modification de l'objet retourné n'a aucun effet sur l'objet d'origine; l'interrogation d'un champ renvoie toujours une référence à un objet dont l'état d'origine est garanti. Travailler avec une propriété qui renvoie une copie peut être très déroutant pour les développeurs, et cette caractéristique est souvent non documentée .
+2

"" Ceci est une erreur, et Microsoft souhaite qu'ils puissent corriger la classe en faisant de Now une méthode au lieu d'une propriété "" Y at-il une preuve de cela n'importe où? Essayez de remplacer tous les mots "propriété" par "méthodes getter et setter" et relisez. Le texte devrait être précis encore et c'est pourquoi je trouve ce genre d'arguments idiot. À mon avis, c'est juste "Je ne comprends pas ce qu'est une propriété, donc je ne l'aime pas" ... Eh bien, une propriété est juste une syntaxe conviviale pour les méthodes getter et setter ... Donc, si vous ne le faites pas comme les propriétés, alors vous n'aimeriez pas getter et setters non plus ... – Jens

3

Vous ne pouvez pas besoin de « get » et préfixes « set », pour le rendre plus comme des propriétés, vous pouvez le faire comme ceci:

public class Person { 
    private String firstName = ""; 
    private Integer age = 0; 

    public String firstName() { return firstName; } // getter 
    public void firstName(String val) { firstName = val; } // setter 

    public Integer age() { return age; } // getter 
    public void age(Integer val) { age = val; } //setter 

    public static void main(String[] args) { 
     Person p = new Person(); 

     //set 
     p.firstName("Lemuel"); 
     p.age(40); 

     //get 
     System.out.println(String.format("I'm %s, %d yearsold", 
      p.firstName(), 
      p.age()); 
    } 
} 
1

Il n'y a aucun mot-clé de la propriété en java (comme vous pouvez le trouver dans C#) le plus proche moyen d'avoir 1 mot getter/setter est de faire comme en C++:

public class MyClass 
{ 
    private int aMyAttribute; 
    public MyClass() 
    { 
     this.aMyAttribute = 0; 
    } 
    public void mMyAttribute(int pMyAttributeParameter) 
    { 
     this.aMyAttribute = pMyAttributeParameter; 
    } 
    public int mMyAttribute() 
    { 
     return this.aMyAttribute; 
    } 
} 
//usage : 
int vIndex = 1; 
MyClass vClass = new MyClass(); 
vClass.mMyAttribute(vIndex); 
vIndex = 0; 
vIndex = vClass.mMyAttribute(); 
// vIndex == 1 
Questions connexes