web-dev-qa-db-fra.com

(non) Propriétés en Java?

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

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

53
Ishmaeel

Il existe un modèle "standard" pour les getters et les setters en Java, appelé Bean properties . Fondamentalement, toute méthode commençant par get, ne prenant aucun argument et renvoyant une valeur, est un getter de propriété pour une propriété nommée en tant que reste du nom de la méthode (avec une lettre de début minuscule). De même, set crée un opérateur de définition 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 des IDE Java généreront ces méthodes si vous leur demandez (dans Eclipse, il suffit de déplacer le curseur sur un champ et d'appuyer sur ctrl-1, puis de sélectionner l'option dans la liste).

Pour ce qui en vaut la peine, pour plus de lisibilité, vous pouvez réellement utiliser is et has à la place de get pour les propriétés de type booléen également, comme dans:

public boolean isAwesome();

public boolean hasAwesomeStuff();
61
Calum

Je suis surpris que personne n'ait mentionné projet lombok

Oui, actuellement, il n'y a pas de propriétés en Java. Il manque également d'autres fonctionnalités.
Mais heureusement, nous avons projet lombok qui tente d’améliorer la situation. Il devient également de plus en plus populaire chaque jour.

Donc, si vous utilisez lombok:

@Getter @Setter int awesomeInteger = 5;

Ce code va également générer getAwesomeInteger et setAwesomeInteger. Il est donc assez similaire à Propriétés auto-implémentées en C # .

Vous pouvez obtenir plus d’informations sur les getters et les setters de Lombok ici .
Vous devriez certainement vérifier autres fonctionnalités / ainsi . Mes favoris sont: 

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

31

"Java Property Support" a été proposé pour Java 7, mais n’a pas été intégré au langage.

Voir http://tech.puredanger.com/Java7#property pour plus de liens et d’informations, si vous êtes intéressé.

6
Cheekysoft

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 certaines des autres langues de la machine virtuelle, Groovy, par exemple, vous obtenez des propriétés remplaçables similaires à C #, par exemple,

int foo

auquel on accède avec un simple .foo et exploite les implémentations par défaut getFoo et setFoo que vous pouvez remplacer si nécessaire.

6
Hank Gay
public class Animal {

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

C'est quelque chose comme les propriétés C #. C'est http://projectlombok.org/

6
dantuch

Vous n'avez peut-être pas besoin de préfixes "get" et "set", pour que cela ressemble davantage à des propriétés, procédez comme suit:

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());
    }
}
4
LEMUEL ADANE

De Jeffrey Richter's livre CLR via C # : (Je pense que ce sont peut-être les raisons pour lesquelles les propriétés ne sont toujours pas ajoutées en Java)

  • Une méthode de propriété peut générer une exception. l'accès au champ ne lève jamais une exception.
  • Une propriété ne peut pas être transmise comme 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 des propriétés est d'effectuer la synchronisation de threads, ce 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 property sera très lent, et Donc. , une méthode est préférée à une propriété. À mon avis, les classes dérivées de MarshalByRefObject ne devraient jamais utiliser de propriétés.
  • Si elle est appelée plusieurs fois dans une ligne, une méthode de propriété peut renvoyer une valeur différente chaque Time; un champ renvoie la même valeur à chaque fois. La classe System.DateTime a une propriété en lecture seule Now qui renvoie la date et l'heure actuelles. Chaque fois que vous interrogez thisproperty, une valeur différente sera renvoyée. C’est une erreur et Microsoft souhaite que Ils pourraient réparer la classe en faisant de Now une méthode plutôt qu’une propriété. La propriété Environment. S TickCount est un autre exemple de cette erreur.
  • Une méthode de propriété peut provoquer des effets secondaires observables; l'accès au champ ne le fait jamais. En d'autres mots , Un utilisateur d'un type devrait pouvoir définir diverses propriétés définies par un type dans N'importe quel ordre qu'il choisit sans remarquer aucun 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; la modification de l’objet retourné n’a donc aucun effet sur l’objet original; L’interrogation d’un champ renvoie toujours une référence à un objet dont il est garanti qu’il fait partie de l’état de l’objet d’origine. Travailler avec une propriété Qui renvoie une copie peut être très déroutant pour les développeurs, et cette caractéristique est fréquemment Non documentée.
3
th1rdey3

La plupart des IDE pour Java généreront automatiquement le code de lecture et de définition pour vous, si vous le souhaitez. Il existe un certain nombre de conventions différentes et un IDE comme Eclipse vous permettra de choisir celle que vous voulez utiliser et même de définir les vôtres.

Eclipse inclut même un refactoring automatisé qui vous permettra d’envelopper une propriété dans un getter et un setter et de modifier tout le code qui accède directement à la propriété, afin de l’obliger à utiliser le getter et/ou le setter.

Bien entendu, Eclipse ne peut modifier que le code qu’elle connaît, toutes les dépendances externes que vous possédez pourraient être rompues par un tel refactoring.

3
Bill Michell

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

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

public void setMyString(string myString) {
    // set it here
}
2
Mark Embling

Je viens de publier des annotations Java 5/6 et un processeur d'annotation pour aider cela.

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

La documentation est un peu légère en ce moment, mais la référence rapide 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).

Un exemple de classe peut ressembler à

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

De nombreux autres exemples sont disponibles et le code généré ne contient aucune dépendance d'exécution.

Envoyez-moi un email si vous l'essayez et le trouvez utile! -- Scott

1
Scott Stanchfield

Si vous utilisez Eclipse, il est capable de générer automatiquement les méthodes de lecture et d’appelage pour les attributs internes. Il peut s’agir d’un outil utile qui permet de gagner du temps.

1
TK.

Il n'y a pas de mot-clé de propriété en Java (comme vous pourriez le trouver en C #), la méthode la plus proche pour avoir 1 getter/setter Word 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
1
Patrick PIGNOL

Comme mentionné précédemment pour Eclipse, l'environnement de développement intégré (IDE) peut souvent créer automatiquement des méthodes d'accesseur.

Vous pouvez également le faire en utilisant NetBeans. 

Pour créer des méthodes d'accesseur pour votre classe, ouvrez un fichier de classe, puis cliquez avec le bouton droit de la souris dans l'éditeur de code source et choisissez la commande de menu Refactorisation, Encapsuler les champs. Une boîte de dialogue s'ouvre. Cliquez sur Sélectionner tout, puis sur Refactor . Voilà,

Bonne chance,

0
levteck