2016-07-09 14 views
0

In C++ gibt es eine Möglichkeit, Daten zu ändern, auch wenn es privat ist:Ändern private Felder in Java unter Verwendung von öffentlichen Methoden

class Foo 
{ 
private: 
    char * i; 
public: 
    char * getInt() {return i;}; 
    Foo() {i="Winter";}; 
} 

int main() 
{ 
    Foo a; 
    strcpy(a.getInt(), "Summer"); //it changes i 
    cout<<a.getInt(); //gives "Summer" 

    return 0; 
} 

Gibt es eine Möglichkeit, dass in Java zu tun?

EDIT: Wenn es gibt, gibt es dann ein Stichwort wie const in C++, um ein solches Verhalten zu verhindern?

+3

Wenn die Variable ein veränderbares Objekt ist, können Sie genau das gleiche in Java tun. Der Unterschied ist lediglich, dass Strings in Java nicht veränderbar sind. – RealSkeptic

+1

Es gibt keine Möglichkeit, ein solches Verhalten zu "verhindern". Wenn Sie einen veränderbaren Variablentyp verwenden und ihn an Benutzer zurückgeben, kann er geändert werden. Wenn Sie einen unveränderlichen Typ verwenden oder änderbare Typen kopieren, bevor sie von Gettern aufgerufen werden, kann sie nicht geändert werden. –

+0

Sie können Reflektionen verwenden, um selbst mit unveränderlichen Objekten zu verfahren. – whitesite

Antwort

2

Java gibt Kopien von Zeigern an Objekte zurück (und Kopien des Werts von Primitiven). Ein solches Objekt ist ein String. Z.B.

class Foo { 
    private String i = "Winter"; 
    public String get() { return i; } 
} 

Nun, das ist vollkommen sicher und nichts (außer Reflexion) kann privates Feld ändern oder es ist Zustand:

void main() { 
    Foo a = new Foo(); 
    String i = a.get(); 
    String j = i + " rocks"; // creates a new string 
    i = "Summer"; // now points to another string 
    System.out.println(a.get()); // still prints "Winter" 
} 

Wenn jedoch Code in der Lage ist, das zurückgegebene Objekt zu ändern, können Sie nicht verhindern, dass es es ändert.

Java hat auch keine eingebaute Möglichkeit, Objekte unveränderlich zu machen, Sie müssen sie so gestalten, dass sie effektiv unveränderbar sind, wie zum Beispiel die Klasse String. Jede Methode, die eine Zeichenkette "modifiziert", erzeugt tatsächlich eine neue unveränderliche Zeichenkette, die unter allen & Threads ohne Sorgen geteilt werden kann.

Wenn Ihre Klasse

war
class Foo { 
    public String i = "Winter"; 
} 

würden Sie nicht sicher sein. Code könnte ändern, worauf dieses Feld verweist.

void main() { 
    Foo a = new Foo(); 
    a.i = "Summer"; // that works. 
    System.out.println(a.i); // prints "Summer" 
} 

Während Sie nicht besonders öffentliche Bereiche haben sollten, wenn Sie es nicht wollen geändert werden, ist es etwas, das hilft: final.

class Foo { 
    public final String i = "Winter"; 
} 
void main() { 
    Foo a = new Foo(); 
    a.i = "Summer"; // Error: final field cannot be modified. 
} 

Die final Schlüsselwort garantiert, dass ein Feld genau einmal vergeben wird. Das Feld muss nach Abschluss des Konstruktors einen Wert haben und kann danach nicht mehr geändert werden. Das referenzierte Objekt kann jedoch immer noch veränderbar sein, lediglich die Bezugnahme darauf ist nicht möglich.