2008-09-16 6 views
51

Also, bis vor kurzem habe ich vorsätzlich ein Java n00b behalten, und meine erste wirkliche Enthüllung brachte einen kleinen Schock mit sich: Java hat keine C# style Eigenschaften!(Nein) Eigenschaften in Java?

Ok, damit kann ich leben. Ich kann jedoch auch schwören, dass ich in einer Codebasis Java-Code für Eigenschaften-Getter/Setter gesehen habe, aber ich kann mich nicht erinnern, wo. Wie wurde das erreicht? Gibt es dafür eine Spracherweiterung? Hat es etwas mit NetBeans zu tun?

Antwort

59

Es gibt ein "Standard" -Muster für Getter und Setter in Java, genannt Bean properties. Grundsätzlich ist jede Methode, die mit get beginnt, keine Argumente annimmt und einen Wert zurückgibt, ein Eigenschaften-Getter für eine Eigenschaft, die als der Rest des Methodennamens bezeichnet wird (mit einem kleingeschriebenen Anfangsbuchstaben). Ebenso erzeugt set einen Setter einer void-Methode mit einem einzelnen Argument.

Zum Beispiel:

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

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

Die meisten Java IDEs werden diese Methoden für Sie generieren, wenn man sie fragt, (in Eclipse es so einfach ist, wie Sie den Cursor auf ein Feld bewegen und Drücken von Strg-1, die Auswahl dann die Möglichkeit, von der Liste).

Für das, was es wert ist, zur besseren Lesbarkeit Sie tatsächlich is und has anstelle von get für boolean-Typ-Eigenschaften verwenden, wie in:

public boolean isAwesome(); 

public boolean hasAwesomeStuff(); 
+0

ich mich die C# Stil Eigenschaft gesehen haben schwören kann irgendwo Syntax in einigem Java-Code, sondern für das Leben von mir Ich kann mich nicht erinnern wo und wie. Das beantwortet meine Frage nicht wirklich, aber ich akzeptiere sie für den Ehrfurchtfaktor. Vielleicht habe ich damals halluziniert. – Ishmaeel

+0

Ich bin mir ziemlich sicher, dass es nicht in Java gemacht werden kann, sorry. Es gibt viele JVM-Sprachen, die erstklassige Unterstützung für diese Art von Dingen haben, obwohl Sie das vielleicht gesehen haben? – Calum

+0

Ist es ein Verstoß gegen diese Konvention, wenn Sie eine Membervariable mit etwas wie "m", "m_" oder "_" voranstellen, aber dann fügen Sie dieses Präfix nicht in den Namen der Eigenschaft ein? – Panzercrisis

2

Meine Java-Erfahrung ist auch nicht so hoch, so dass jeder frei ist, mich zu korrigieren. Aber AFAIK ist die allgemeine Konvention zwei Methoden zu schreiben, wie so:

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

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

Wenn Sie Eclipse verwenden dann hat es die Fähigkeiten zur automatischen Erzeugung der Getter und Setter-Methode für die internen Attribute, kann es eine sehr nützlich sein, und zeitsparendes Werkzeug.

5

Die Bohne Konvention ist der Code wie folgt zu schreiben:

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

In einigen der anderen Sprachen auf der JVM, zB Groovy, erhalten Sie overridable Eigenschaften ähnlich wie C#, zum Beispiel

int foo 

, auf die mit einer einfachen .foo zugegriffen wird, und nutzt standardmäßig getFoo und setFoo Implementierungen, die Sie bei Bedarf überschreiben können.

3

Die meisten IDEs für Java wird automatisch Getter und Setter-Code erzeugen für dich, wenn du willst. Es gibt eine Reihe von verschiedenen Konventionen, und eine IDE wie Eclipse ermöglicht es Ihnen, auszuwählen, welche Sie verwenden möchten, und Sie können sogar Ihre eigenen definieren.

Eclipse enthält sogar ein automatisiertes Refactoring, mit dem Sie eine Eigenschaft in einen Getter und Setter umwandeln können und den gesamten Code, der direkt auf die Eigenschaft zugreift, um den Getter und/oder Setter zu verwenden.

Natürlich kann Eclipse nur Code ändern, den es kennt - alle externen Abhängigkeiten, die Sie haben, könnten durch ein solches Refactoring zerstört werden.

1

Ich gebe gerade Java 5/6 Annotationen und einen Annotationsprozessor frei, um dies zu unterstützen.

Check out http://code.google.com/p/javadude/wiki/Annotations

Die Dokumentation ist ein wenig Licht im Moment, aber die QuickRef sollte die Idee zu vermitteln.

Im Grunde generiert es eine Oberklasse mit den Getter/Setter (und viele andere Optionen zur Code-Generierung).

könnte eine Beispielklasse aussehen

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

Es gibt viele weitere Proben zur Verfügung stehen, und es gibt in den generierten Code keine Laufzeitabhängigkeiten.

Senden Sie mir eine E-Mail, wenn Sie es ausprobieren und nützlich finden! - Scott

6
public class Animal { 

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

Dies ist so etwas wie C# -Eigenschaften. Es ist http://projectlombok.org/

+1

Punkt zu beachten: Dies würde als eine Sprachenerweiterung zählen und neigt dazu, IDEs sehr verwirrt zu machen. – millimoose

+2

@millimoose Sie brauchen nur ein Plugin für IDE. Leider braucht jeder, der einen solchen Code benutzt. – dantuch

+2

"Sie brauchen ein Plugin für die IDE" bringt mich dazu, eine Zeitung aufzustellen und die dafür Verantwortlichen zu swaten. (Obwohl dies wohl mehr in den Fällen ist, in denen die IDE-Konfiguration das primäre Build-System für eine Codebasis ist.) – millimoose

29

Ich bin überrascht, dass niemand project lombok erwähnt

Ja, gibt es derzeit keine Immobilien in Java. Es gibt noch einige andere fehlende Funktionen.
Aber zum Glück haben wir project lombok, die versucht, die Situation zu verbessern. Es wird auch immer beliebter jeden Tag.

Also, wenn Sie lombok verwenden:

@Getter @Setter int awesomeInteger = 5; 

Dieser Code wird getAwesomeInteger und setAwesomeInteger als auch generieren. Es ist also sehr ähnlich zu C# auto-implemented properties.

Sie können mehr Informationen über Lombok Getter und Setter here erhalten.
Sie sollten auf jeden Fall auch other features auschecken. Meine Favoriten sind:

Lombok ist gut integriert mit IDEs, so dass es wie generierten Methoden zeigen, wird, wenn sie existierten (Anregungen, Klasse Inhalt, gehe zur Deklaration und Refactoring).
Das einzige Problem mit Lombok ist, dass andere Programmierer es vielleicht nicht wissen. Sie können immer den Code delombok, aber das ist eher ein Workaround als eine Lösung.

+3

Methoden, die Sie nicht im Code sehen können, scheint noch schlimmer. Auto-Eigenschaften in C# sind nur die halbe Wahrheit - es geht hauptsächlich darum, verwandte Logik zu benennen und zu gruppieren. –

+6

@JonnyLeeds gut, wie ist es überhaupt schlecht? Sie können sie im Code sehen, indem Sie '' Getter'' und '' @Setter''Anmerkungen sehen, und sie werden auch in anderen Symbolleisten angezeigt (wie Umriss oder Vorschläge). –

+0

Anmerkungen werden nicht vererbt - dadurch wird Ihre Fähigkeit verfälscht Objektorientierte Entwicklung. Wenn du OO machst, dann weißt du, dass es sehr wenig Grund gibt, Getter und Setter zu haben. Es ist viel besser, das Verhalten als das Datenmodell offenzulegen. Wir sind weit darüber hinaus, wo jemand Structs (Beans) verwenden sollte. –

2

Von Jeffrey Richters Buch CLR via C#: (ich glaube, diese könnten die Gründe sein, warum Eigenschaften sind in JAVA noch nicht hinzugefügt)

  • Eine Eigenschaft Methode eine Ausnahme auslösen kann; Feldzugriff löst niemals eine Ausnahme aus.
  • Eine Eigenschaft kann nicht als out oder ref Parameter an eine Methode übergeben werden; ein Feld kann.
  • Eine Property-Methode kann lange dauern. Der Feldzugriff wird immer sofort abgeschlossen. Ein häufiger Grund für die Verwendung von Eigenschaften ist die Thread-Synchronisierung, , die den Thread für immer stoppen kann, und daher sollte eine Eigenschaft nicht verwendet werden, wenn Thread-Synchronisierung erforderlich ist. In dieser Situation ist eine Methode bevorzugt. Wenn auf Ihre Klasse remote zugegriffen werden kann (z. B. ist Ihre Klasse von System.MarshalByRefObject abgeleitet), ist der Aufruf der Eigenschaftsmethode sehr langsam und daher wird eine Methode einer Eigenschaft als vorgezogen. Meiner Meinung nach sollten Klassen, die von MarshalByRefObject abgeleitet sind, niemals Eigenschaften verwenden.
  • Wenn sie mehrmals hintereinander aufgerufen wird, gibt eine Eigenschaftsmethode möglicherweise einen anderen Wert zurück time; Ein Feld gibt jedes Mal denselben Wert zurück. Die Klasse System.DateTime verfügt über eine schreibgeschützte Now-Eigenschaft, die das aktuelle Datum und die aktuelle Uhrzeit zurückgibt. Jedes Mal, wenn Sie diese Eigenschaft abfragen, wird ein anderer Wert zurückgegeben. Dies ist ein Fehler, und Microsoft möchte, dass sie die Klasse reparieren können, indem Sie Now eine Methode anstelle einer Eigenschaft vornehmen. Environment TickCount Eigenschaft ist ein weiteres Beispiel für diesen Fehler.
  • Eine Eigenschaftsmethode kann beobachtbare Nebenwirkungen verursachen; Feldzugriff funktioniert nie. In anderen Wörtern sollte ein Benutzer eines Typs in der Lage sein, verschiedene Eigenschaften festzulegen, die durch einen Typ in in beliebiger Reihenfolge definiert sind, ohne ein anderes Verhalten im Typ zu bemerken.
  • Eine Eigenschaft Methode kann zusätzliche Speicher benötigen oder einen Verweis auf etwas zurückzugeben, die nicht tatsächlich einen Teil des Zustandes des Objekts ist, so dass das zurückgegebene Objekt Modifizieren auf dem ursprünglichen Objekt keine Wirkung hat; Das Abfragen eines Felds gibt immer einen Verweis auf ein Objekt zurück, das garantiert Teil des ursprünglichen Objektstatus ist. Arbeiten mit einer Eigenschaft , die eine Kopie zurückgibt, kann für Entwickler sehr verwirrend sein, und dieses Merkmal ist häufig nicht dokumentiert.
+2

"" Dies ist ein Fehler, und Microsoft möchte, dass sie die Klasse reparieren können, indem Sie jetzt eine Methode anstelle einer Eigenschaft erstellen. "" Gibt es irgendwo einen Hinweis darauf? Versuchen Sie, alle Wörter "property" durch "getter and setter methods" zu ersetzen und erneut zu lesen. Der Text sollte immer noch genau sein und deshalb finde ich diese Art von Argumenten albern. Meiner Meinung nach ist das nur "Ich verstehe nicht, was eine Eigenschaft ist, deshalb mag ich sie nicht" ... Nun, eine Eigenschaft ist nur freundliche Syntax für Getter- und Setter-Methoden ... Also, wenn du es nicht tust Wie Eigenschaften, dann magst du Getter und Setter auch nicht ... – Jens

3

Sie für nicht brauchen kann „get“ und „set“ Präfixe, um es ähnliche Eigenschaften aussehen, können Sie es so machen kann:

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

Es gibt keine Eigenschaft Schlüsselwort in Java (wie Sie es in C#) den nächsten Weg 1 Wort Getter haben, finden können/Setter ist wie in C zu tun ++:

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