Da der Moment, den Sie etwas tun, wie
public float returnSomething(String theThing) {
switch (theThing) {
case "height":
return height;
case "rotation" :
return rotation;
case "width":
return width;
default:
return 0;
}
}
Ich kann die nächste Frage für Stack Overflow, "Warum ist meine Höhe immer 0? "
Und dann Code schreiben wie
public class GameThingy {
//...
private void doStuff(GameObject gameObject) {
float gravity = 5*gameObject.returnSomething("hieght");
gameObject.setSomething("velocyty", gravity+50);
}
}
Technisch, sobald Sie einen Tippfehler überall machen, werden Sie Probleme haben, die Ursache des Problems zu finden. Das, und du hast Glück, dass die Felder alle float
sind, müssen sie nicht sein.
Bearbeiten: Übrigens ist dies ein typisches Problem bei der Definition des Interessensbereichs in einigen Datenbankabfragen. Wie in, muss das Feld, das Sie suchen, durch eine String
angeben.
Ein reales Beispiel ist RealmQuery<T>
.
A RealmQuery<T>
sieht wie folgt aus:
RealmQuery<User> query = realm.where(User.class);
// Add query conditions:
query.equalTo("name", "John");
// Execute the query:
RealmResults<User> result1 = query.findAll();
Wo sie die Klasse übernehmen User
so etwas wie dieses:
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Eine interessante Anmerkung ist, dass Realm erstellt einen "Proxy-Unterklasse", wo sie neu definieren die setName
und getName
Methoden (aka, benötigen Sie Getter/Setter, um einige Systeme arbeiten zu lassen! Sie nehmen an, Sie haben sie!)
Aber was hier wichtig ist, ist, dass Sie den Feldnamen mit "name"
angeben müssen.
Später kann jemand einen Tippfehler machen, oder Sie einfach nicht daran denken, die Felder weg von der Oberseite des Kopfes. In diesem speziellen Fall neigen sie dazu, ein Metamodell (etwas, das den Namen der Felder für Sie speichert) zu dem Zweck zu erstellen, dass Sie Strings verwenden müssen, um auf Feldnamen verweisen.
Zum Beispiel in Criteria API, statt
Root<Pet> pet = cq.from(Pet.class);
cq.select(pet.get("name"));
Sie haben das Metamodell wie folgt aus:
Root<Pet> pet = cq.from(Pet.class);
cq.select(pet.get(Pet_.name));
So ist es entfällt die Notwendigkeit für String
s.
Und ähnlich, was neige ich dazu, mit Realm zu tun, ist, dass ich ein „Metamodell“ erstellen (obwohl Sie jetzt es erzeugt für Sie automatisch mit RealmFieldNamesHelper haben kann):
public class User
extends RealmObject {
@PrimaryKey
private long id;
private String name;
public static enum Fields { //this is the "metamodel"
ID("id"),
NAME("name");
private String fieldName;
Fields(String fieldName) {
this.fieldName = fieldName;
}
public String getField() {
return fieldName;
}
@Override
public String toString() {
return getField();
}
}
}
Und so können Sie die ersetzen Abfrage wie so
RealmResults<User> result2 = realm.where(User.class)
.equalTo(User.Fields.NAME.getField(), "John")
.or()
.equalTo(User.Fields.NAME.getField(), "Peter")
.findAll();
Aber mit Getter und Setter, haben Sie bereits die Art Sicherheit, und Sie haben bereits die Methoden, die Sie haben, um die Oberseite des Kopfes nicht mehr erinnern aus - und so, Sie haben die Fehler bei der Kompilierungszeit.
So Ihre Frage zu beantworten, ist der Grund, warum es eine schlechte Praxis ist in Java zu Variablen durch string name zu beziehen, weil
1.) Tippfehler passieren kann, und der Fehler tritt nur in Laufzeit kompilieren, keine Zeit
2.) es ist nicht typsicher; Sie haben Glück, dass Sie float
s zurück, egal was in diesem Beispiel, aber der Moment kann es ein String
sein, müssen Sie Object
zurückgeben und es oder public <T> T get(String field) { ... }
verwenden und wer auch immer die Methode ruft müssen genau wissen, was sie erhalten - auch Laufzeitfehler anfällig.
Der Standardfall, den Sie im zweiten Beispiel hinzufügen müssen, veranschaulicht die Schwäche der zweiten Methode. Sie geben ein gewisses Maß an Sicherheit auf, indem Sie sich erlauben, eine beliebige Saite zu passieren. Wenn Sie beispielsweise eine Dimension enum mit Werten wie "HEIGHT", "ROTATION", "WIDTH" usw. angeben würden, könnten Sie eine ähnliche Funktionalität wie im zweiten Beispiel erreichen, jedoch mit zusätzlicher Typ-Sicherheit. (Alternativ könnten Sie die @StringDef Annotation verwenden ...) – stkent
Mit einem Getter direkt speichern würde eine 'switch' Anweisung (jedes Mal, wenn Sie einen Wert erhalten möchten, müssen Sie alle Fälle umschalten) – Hacketo
Ich werde nie wechseln weil, wenn ich Integer, Float, Strings und boolesche Variablen habe, muss ich noch 4 verschiedene Funktionen einrichten und alle Fälle angeben + es kann eine Chance geben, dass ich eine falsche Zeichenfolge (String theThing) sende und keine Übereinstimmung gefunden wurde, Zweiter Grund Eclipse und Android Studio generiert Getter und Setter für mich, damit ich mich auf meine Logik konzentrieren kann, nicht auf Getter und Setter –