2016-03-24 26 views
0

Ich darf Klasse A nicht ändern, aber ich muss den Wert von 'a' bekommen (im Konstruktor gesetzt). Kann mir jemand sagen, wie ich das mache? Jede andere Lösung scheint mir erlaubt ist nicht für die Öffentlichkeit in keiner Weise, kein Wechsel zu Änderungen an der Klasse A einen Getter in der Klasse A. vorzuschlagen usw. Die Magie in der Klasse B passieren hatjava: private Variable aus einer anderen Klasse holen, ohne einen Getter zu setzen

public class A{ 
    private int a; 
    public A(int x){ 
     a = x * 10; 
    } 
} 

public class B{ 
    public B(int x){ 
     A instA = new A(x); 
    } 

    public int geta(){ 
     ??? 
    } 
} 

PS: Diese Frage wurde geposted, weil jede ähnliche Frage mit der Änderung der Klasse A beantwortet wurde, obwohl ich das nicht tun darf. Aber da es nur Nachdenken zu geben scheint, kann diese Frage geschlossen werden. Danke Jungs und Mädels.

+0

Wenn die Membervariable privat ist, ist die einzige Möglichkeit, auf sie zuzugreifen, eine Methode. –

+3

Sie dürfen keinen Getter zu A hinzufügen, aber dürfen Sie A in irgendeiner Weise modifizieren? Wenn dies der Fall ist, könnten Sie 'private int a;' in 'public int a;' ändern. Bitte geben Sie auch an, WARUM Sie keinen Getter hinzufügen dürfen. –

+4

siehe: http://stackoverflow.com/questions/1196192/how-do-i-read-a-private-field-in-java –

Antwort

0

Die beste Entscheidung ist, einen Getter zu haben. Es ist die sicherste und sauberste Lösung, wenn es um die Programmierung von Best Practices geht.

Es ist möglich, zu erreichen, was Sie Reflektion verwenden möchten - Sie das Feld nach Name (was, wenn die Namensänderungen in einer zukünftigen Version der Klasse?) Und der Extrakt ist es Wert wie folgt zu finden:

A a = new A(5); 
Field field = A.getField("a"); 
field.setAccessible(true); 
int value = field.get(a); 

Aber bedenken Sie, dass dies als super hacky gilt und es stark davon abraten.

+0

Teilweise zustimmen, aber eine weitere Zeile sollte vor dem Zugriff auf das Feld hinzugefügt werden: 'field.setAccessible (true);' – Aliaxander

+0

@Alixander wahr, dass. –

2

Das ist der springende Punkt private Felder; Sie sind außerhalb des Umfangs der umschließenden Klasse nicht zugänglich.

Sie haben folgende Möglichkeiten:

  1. ändern, dass die Klasse einen Getter
  2. ändern Sie Ihr gesamtes Design, entweder diesen Wert nicht brauchen zu liefern; oder einen anderen Weg finden, um es zu beiden Klassen zur Verfügung zu stellen
  3. Nicht empfohlen: Verwendung Reflexion und seine Fähigkeit, die „private“ Schutz zur Laufzeit
+0

Danke. Ich verstehe den Punkt der privaten Felder. Ich denke, der Wortlaut der Übung ist falsch. Ich glaube nicht, dass Reflexion die Lösung ist, die wir verwenden sollen. Ich hatte gehofft, jemand würde mich hier auf eine Lösung hinweisen, die ich gerade nicht sehen konnte. Ich denke, wir dürfen die gegebenen Methoden nicht ändern, aber fügen Sie einige hinzu, sonst scheint es nur eine Reflexion zu geben ... – Peter

0

hier außer Kraft zu setzen ist, wie Sie es tun können

public int geta(){ 
     Field field; 
     int x = 0; 
     try { 
      field = A.class.getDeclaredField("a"); 
      field.setAccessible(true); 
      x = field.getInt(this.a); 
     } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
    System.out.println(x); 
    return x; 
}