# warum Setter/Getter



## Guest (10. Mrz 2007)

hey, ihc hab mal ne ganz dumme Frage,warum benutzt man überhaupt Getter/Setter -Methoden ,
bzw. gibts irgendeinen technischen Grund warum man nicht einfach per public auf die Varibalen zugreifen sollte?


----------



## Marco13 (10. Mrz 2007)

Wenns danach http://www.java-forum.org/de/viewtopic.php?t=4354 noch Fragen gibt, sag bescheid.


----------



## thE_29 (12. Mrz 2007)

Bei Punkt 2: Wenn ich also den Typ umändere brauche ich nur die getter/setter Methoden umbauen und dann gehts..
LOOL.. Und wenn der Typ anders ist, brauche natürlich net überall dort wo ich get/set habe die Typen ändern.. Nene..


Desweiteren finde ich es ja auch "blöd" das wenn man eine Klasse mit Objekten hat, zB sowas

Gegeben sei eine Klasse B!


```
public class A
{
private B node;
public void setB(B b)
{ this.node = b;
}

public B getB()
{
return this.node;
}
```

So, da in Java ja alles call by reference ist, ist für mich die setter Methode total umsonst!

Weil wenn ich sage getB() und dann diese Klasse B verändere, so wird ja das eigentliche B verändert (call by value).

Somit wäre die Methode setB(..) umsonst, da es ja schon gesetzt ist! 
Auf das hat mich ein C++ Programmierer hingewiesen, der diese Problem in C++ damit umgeht, das er bei den get Methoden immer "Konstanten" zurückliefert. Also Objekte die nicht veränderbar sind!

Gibt es in Java sowas auch?! Weil das Wort const an sich gibt es ja, bzw der JBuilder machts blau :bae:


----------



## Marco13 (12. Mrz 2007)

In Java gibt es NUR *call by value*. Da aber (abgesehen von denen mit primitiven Typen) alle Variablen _Referenzen_ sind, "fühlt es sich manchmal an" wie call by reference. 

Trotzdem werde ich weiterhin sowas sagen wie "es wird ein Objekt zurückgegeben", obwohl man eigentlich sagen müßte "es wird die Kopie einer Referenz auf ein Objekt zurückgeliefert". Dabei ist "Objekt" und "(Kopie einer) Referenz auf ein Objekt" der Einfachheit synonym verwendet.

Die Methode setB in deinem Beispiel dient nur dem Zweck, zu sagen, welches Objekt zurückgeliefert werden soll, wenn man getB aufruft. Und die Methoden sind NICHT sinnlos: Wenn du später zur Erkenntnis gelangst, dass IMMER, wenn ein neues 'b' gesetzt wird, eine bestimmte Aktion ausgeführt werden muß, musst du nur

```
public void setB(B b)
    {
        this.b = b;
        eineBestimmteAktion();
    }
```
machen. Andernfalls müßtest du überall, wo (verstreut im ganzen Programm) die Zeile

```
einA.b = irgendeinB();
```
auftaucht, eine Änderung durchführen.


----------



## Marco13 (12. Mrz 2007)

Nachtrag: Das Wort 'const' ist in Java reserviert (genau wie goto) wird aber nicht verwendet (genau wie goto). In manchen Fällen, erfüllt "final" eine _ähnliche_ Bedeutung wie "const" in C++, aber es ist NICHT die gleiche! ("final" ist etwas "schwächer"). Wenn du willst, dass das Objekt, das mit get() zurückgegeben wird, nicht verändert werden darf, darfst du es nicht zurückgeben. Es gäbe da (je nach Zusammenhang) verschiedene "Workarounds" - z.B. get-Funktionen anzubieten, für das, was man sich eigentlich von dem Objekt holen würde, oder ein "immutability-Wrapper" wie z.B. bei Collections.unmodifiableCollection
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html#unmodifiableCollection(java.util.Collection)


----------



## thE_29 (12. Mrz 2007)

Naja, bei Methoden bewirkt final das die Methoden nicht überschrieben werden können!

Und es ging mir ja nicht darum, das Objekt zu verändern, sondern eben das die set Methode eigentlich unnötig wäre, weil es ja call by value (tschuldige mein Fehler.. Verwechsel diese 2 immer - besser das mal gleich oben aus ) ist.


Und der C++ Programmierer hat mir genauso das Bsp was du oben gebracht hast, als Argument für get/set Methoden! Eben wenn man etwas ändern/loggen etc will wenn die Variable geändert wird, sind solche get/set Methoden sicher vorteilhafter 


Aber wie gesagt, der Punkt 2 in den FAQ ist einfach nur dämlich. Denn wenn ich den Typ ändert, muss ich den Typ bei den get/set Methoden auch ändern (also dort wo sie benutzt werden). Außer ich arbeite immer mit Object und mache ein if instanceof und caste es dann hin... (was aber kaum jemand tun wird).



Nachtrag 2: Warum heitß das eigentlich call by value?! Das ist doch totale Blödaussage..

Zitat call by value: 

In diesem Beispiel ist zu sehen, dass die beiden Variablen a und b lediglich ihre Werte an die Funktion test übergeben, aber im Gegensatz zu einem Referenzparameter dabei unverändert bleiben.


Tjo, dh, bei call by value müsste es immer unverändert bleiben! Da man in Java aber net explizit sagen kann sei Referenz oder sei eine "Kopie" würde ich eher dazu tendieren das man sagt, es ist call by reference.


Aber dann findet man wieder sowas: 

In der Sprache Java wird bei primitiven Datentypen automatisch ein Wertparameter (call by value) verwendet. Bei komplexen Datentypen wird kein richtiger Referenzparameter (aber sicher kein call by value - da dies dazu führen würde das es unverändert bleibt) verwendet. Es wird eine Kopie der Referenz übergeben, die aber auf das gleiche Objekt verweist. Somit hat eine Änderung im Objekt auch bei der aufrufenden Methode Auswirkungen.

Da verstehe ich net wirklich warum man eine Kopie von einem Objekt das eigentlich auf das gleiche zeigt (also gleichen Adressbaum - wo ist das dann eine Kopie?!) übergibt, anstatt gleich das gleiche Objekt


----------



## Marco13 (12. Mrz 2007)

Der zweite Punkt ist nicht dämlich, du hast ihn nur falsch verstanden :bae: Es geht dabei darum, dass die zugrundeliegene Implementierung der Map sich ändert. Sinngemäß

```
public String getValue(String k)
{
    return hashMap.get(k);
}
```
Und dann entscheidet man sich, ... *bla, Beispiel aus der Luft greif* das mit Properties zu machen

```
public String getValue(String k)
{
    return RessourceBundle.blablup.getValue(k);
}
```
Du weißt sicher, was gemeint ist... :roll:

Und das final <-> const ... Wie gesagt: In manchen Fällen ist es _ähnlich_, z.B. bei der Parameterübergabe

```
// C++
void foo(const int i)
{
    i = 3; // Fehler!
}

// Java
void foo(final int i)
{
    i = 3; // Fehler!
}
```
aber bei Referenzen ist C++ da restriktiver. In C++ gibt's da ja auch noch mehr Möglichkeiten. Bin da etwas aus der Übung, aber soweit ich weiß sind da ja (wenn mans drauf anlegt) tatsächlich solche abstrusen Deklarationen wie
const int const * doSomething(const int const * arg) const { ... }
möglich.... Also eine Methode, die eine konstanten Zeiger auf einen Konstanten int bekommt, einen konstanten Zeiger auf einen konstanten int zurückliefert, und dabei das Objekt konstant läßt. (Vielleicht syntaktisch nicht ganz richtig, aber sowas ähnliches ist glaubich möglich)


----------



## thE_29 (12. Mrz 2007)

Achso hat er das gemeint 

Tjo, dann habe ich das falsch verstanden :bae:

Habe vorher noch was dazugehängt, zum Thema call by value /call by reference!


----------



## Marco13 (12. Mrz 2007)

Ja, habs gesehen, habe jetzt nur gewartet bis du den synchronized-Block verlassen und durch deinen Post den Lock wieder freigegeben hast :wink:

Frag den C++-Menschen, den du oben erwähnt hast, mal ein bißchen zu Pointern aus. Man könnte (zur Verdeutlichung(!)) sagen, dass man in Java NUR mit Pointern hantiert:

```
// Java
Object x = new Object(); 

// C++
Object *x = new Object();
```
Das *x ist dabei sozusagen eine "ganz normale Variable". Und diese Variable enthält als WERT (value) die Speicherstelle, an der das neue Objekt liegt. In Java "läßt man nur das Sternchen weg".

Wenn man diese Referenz (Java) bzw. Pointer (C++) dann an eine Funktion übergibt, wird die standardmäßig by value übergeben. 

```
// Java:
Object x = new Object(); 
foo(x);

void foo(Object y)
{
    y ist hier eine Kopie der Referenz x (call by value)
}


// C++
Object *x = new Object();
foo(x);

void foo(Object *y)
{
    *y ist hier eine Variable, die die Speicherstelle enthält, die auch in *x steht (also die Stelle, wo das Objekt liegt)
    *y ist also eine Kopie von *x (call by value)
}
```

In C++ gibt's dann nochmmal eine andere Form von Referenzen 
void foo(int& x)
aber ... ich belasse es erstmal dabei.


----------



## thE_29 (12. Mrz 2007)

Ich kann selber auch C++ 

Nur bin ich selber zZ in Java eingetieft und ich kriege immer und immer mehr Probleme mit Java desto tiefer man reingeht (alleine schon das mit dem EventDispatchThread das nachzeichnen das hintereinanderabarbeiten von Events die eigentlich schon vorher gemacht worden sind oder während der EDT eine Komponente X zeichnet, möchte ich gerne Lade.. hinschreiben, nur da das auch vom EDT gemacht wird, sehe ich in 5/10 Fällen nix...)


Und dein unten angeschnittenes Bsp mit dem int darf man nicht heranziehen, da das in C++ ja auch ein primitiver Datentyp ist 

Da du ja auch int * p = 1; gar nicht sagen kannst.. (dann würde er dir auf die Adresse 1 zeigen)

Hingegen int i = 1; und dann int *p = &i; würde gehen!



```
class B
{
public:
	int a;
	B(){
		a = 12;
	}
};

void test(B* b)
{
	b->a = 23;
}


int main(int argc,char *argv[])
{
	B *testB = new B();
	printf("\nVorher %d",testB->a);
	test(testB);
	printf("\nNachher: %d", testB->a);
}
```

Ausgabe wäre: Vorher 12
Nachher: 23


----------



## Jango (12. Mrz 2007)

Du hast den Destructor vergessen:


```
~B(){}
```


----------



## thE_29 (13. Mrz 2007)

Wozu den 

Soll er mir den int wieder freigeben? :bae:


----------



## Jango (13. Mrz 2007)

thE_29 hat gesagt.:
			
		

> Wozu den
> 
> Soll er mir den int wieder freigeben? :bae:



Nein, nur wegen dem Stil (mal so gelernt)


----------



## Leroy42 (13. Mrz 2007)

Jango hat gesagt.:
			
		

> ```
> ~B(){}
> ```


ist für mich dasselbe wie ein leerer Konstruktor in Java

```
class Jango extends HobbitImBlutrausch {
  public Jango() {
  }
  ...
}
```

Dient also nur dazu beim Ansehen im Editor dem Monitor
ein paar schwarze Pixel mehr zu gönnen um ihn zu schonen.  :bae:


----------



## Jango (13. Mrz 2007)

Leroy42 hat gesagt.:
			
		

> ```
> class Jango extends HobbitImBlutrausch {
> public Jango() {
> }
> ...



Und wie bitte, soll ich das verstehen?  :?


----------



## André Uhres (14. Mrz 2007)

get- und set-Methoden sind besonders nützlich für die *Introspection *und *Customization *von Beans
bei der Anwendungsentwicklung mit Application Buildern. So lässt z.B. ein Methodenpaar

```
public String getName()
public void setName(String n)
```
auf eine Property *name *vom Typ *String *schließen. 
Bei Properties des Datentyps *boolean *ist auch die is-Methode für den lesenden Zugriff möglich. 
Wird als Datentyp ein Array gefunden und gibt es für diese Property noch zusätzliche set- und get-Methoden 
mit einem Index vom Typ *int* als Parameter, so wird daraus auf eine *Indexed Property* geschlossen.


----------



## The_S (14. Mrz 2007)

Leroy42 hat gesagt.:
			
		

> ```
> class Jango extends HobbitImBlutrausch {
> public Jango() {
> }
> ...



Hui, ich hab ne Erbin


----------



## Wildcard (14. Mrz 2007)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> Hui, ich hab ne Erbin


Und wenn man von '...' auf weiteren Code schließen darf, dann kann sie sogar mehr als du  :bae:


----------



## The_S (14. Mrz 2007)

Joa, das hier z. B.


```
public String korrigiereTextNachDeutscherRechtschreibung(String text) {
   // sehr viel wirres Zeug
   return korrigierterText;
}
```

(es wurde bewusst public ausgewählt *duck* *wegrenn*)


----------



## Jango (15. Mrz 2007)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> (es wurde bewusst public ausgewählt *duck* *wegrenn*)



Wie willst vor mir wegrennen?  ???:L


----------



## The_S (15. Mrz 2007)

lol ... wenn die andern jetzt wüssten, was wir wissen, dann würden sie die aussage jetzt evtl. auch verstehen ...

aber aufgrund der tatsache, dass sie nicht wissen, was wir wissen, glauben sie jetzt bestimmt was falsches zu wissen

weißt du?


----------



## Jango (15. Mrz 2007)

ähh... ja - natürlich weiß ich


----------



## André Uhres (16. Mrz 2007)

Ich hätte dazu noch einen nützlichen Getter:

```
public String getWasDieAnderenNichtWissen(){...}
```
 :lol:


----------



## The_S (16. Mrz 2007)

:lol:


```
public String getWasDieAnderenNichtWissen(NichtWisser user){
   if (!user.equals(jango) && !user.equals(hobbit)) {
      return null;
   }
   else {
      return topSecret;
   }
}
```


----------



## André Uhres (16. Mrz 2007)

@Hobbit:   :lol: du hast die beiden returns vertauscht!


----------



## The_S (16. Mrz 2007)

Ähm ... nein!


----------

