# null-referenz



## UdoKessler (5. Apr 2009)

Bin in meinem Buch grad im Kapitel über Objekte u Referenzen..
Beim Thema null-Referenz verstehe ich etwas nicht.

Zitat:



> Mit null lässt sich eine ganze Menge machen. Der Haupteinsatz sieht vor, damit uninitialisierte Referenzvariablen zu kennzeichnen, also auszudrücken, dass eine Referenzvariable auf kein Objekt verweist.
> 
> bsp:
> Point  p = null;




Wozu soll es gut sein, eine Referenz anzulegen, die auf kein Objekt zeigt?


Gruß
Udo


----------



## faetzminator (5. Apr 2009)

Wenn du eine Abhängigkeit von 0-n oder 1-n von Objekt X nach Y hast, kannst du eine List erstellen, welche .size() = 0 haben kann. Wenn du allerdings eine Abhängigkeit von 0-1 hast, ist das Objekt null oder nicht null...
Beispiel für null:

```
private void print(String s) {
    print(s, null);
}

private void print(String s, PrintStream ps) {
    if (ps == null) {
        ps = System.out;
    }
    ps.println(s);
}
```
Klar, du könntest oben auch print(s, System.out) übergeben, aber so ist die Methode schon gegen einen Nullpointer von ps gesichert.


----------



## Wildcard (5. Apr 2009)

Variablen müssen immer auf irgendetwas zeigen. Zu einem Zeitpunkt an dem man noch nicht auf etwas sinnvolles zeigen kann, zeigt man auf null.


----------



## UdoKessler (5. Apr 2009)

@Wildcard
Aber ich kann doch die Referenz dann erstellen, wenn ich auch
das Objekt erstelle. Wieso sollte ich die Referenz im Voraus
anlegen?

@fatzminator
Ähh könntest Du das bitte nochmal für Dummies(wie mich) beschreiben?
Ich meine mit einfacheren Worten/Beispielen?
Verstehe Dich nämlich nicht


----------



## Schandro (5. Apr 2009)

> @Wildcard
> Aber ich kann doch die Referenz dann erstellen, wenn ich auch
> das Objekt erstelle. Wieso sollte ich die Referenz im Voraus
> anlegen?


Nein, dass kannst du nicht (immer). Wenn du die Referenz z.b. als Membervariable brauchst und das dazugehörige Object erst irgendwann in einer Methode erstellt wird...


----------



## faetzminator (5. Apr 2009)

Also, einfaches Beispiel:
Die Klasse Man hat ein Feld Wife wife, doch was macht mann, wenn dieser Man nicht verheiratet ist? wife auf null lassen, wäre wohl die beste Möglichkeit.


----------



## UdoKessler (5. Apr 2009)

Schandro hat gesagt.:


> Nein, dass kannst du nicht (immer). Wenn du die Referenz z.b. als Membervariable brauchst und das dazugehörige Object erst irgendwann in einer Methode erstellt wird...



Ach Du meinst, wenn ich eine Methode aufrufe, welche ein Objekt erstellt, dann
übergebe ich dem Methodenaufruf eine null-initialisierte Refernz als Argument?
Und diese null-referenz zeigt nach dem Methodenaufruf dann auf das erzeugte
Objekt?


----------



## UdoKessler (5. Apr 2009)

faetzminator hat gesagt.:


> Also, einfaches Beispiel:
> Die Klasse Man hat ein Feld Wife wife, doch was macht mann, wenn dieser Man nicht verheiratet ist? wife auf null lassen, wäre wohl die beste Möglichkeit.



Das ist mal ein gutes Beispiel, danke!
So weit hab ich es verstanden


----------



## faetzminator (5. Apr 2009)

Noch ein Bisschen Code zu meinem Beispiel

in Klasse Man

```
public boolean isMarried() {
    return wife != null;
}
```
irgendwo...

```
Man man = new Man(...);
...
if (man.isMarried()) {
    Wife wife = man.getWife();
    ...
}
...
```


----------



## UdoKessler (5. Apr 2009)

@faetzminator (was fürn name ;-) )

Also, hab das mal zum testen kurz geschrieben. Wenn ich damit rumspielen
kann, versteh ichs meistens besser..:

Klasse wife

```
public class wife {
int age=0;
int money=1000;

}
```



Klasse Man und main

```
public class man {
    int age=0;
    int money=0;
//    wife wife = null;
    wife wife = new wife();
    
    public boolean isMarried() {
        
        return wife != null;
    }
    
    public static void main(String[] args) {

        man man = new man();
        man.age=30;
        man.money=1000;
        
        System.out.println(man.money);
        System.out.println(man.isMarried());
        
        
    }

}
```


Jetzt ist die Konsolenausgabe in Abhängigkeit des wife-objekts (höhö)
entweder true oder false. So meintest Du das, oder?


----------



## faetzminator (5. Apr 2009)

1. Bitte an die Konventionen halten, Klassen sollten mit einem Grossbuchstaben anfangen, also z.B. "Wife wife = new Wife()"
2. Beim Erstellen von Man wird ja in wife automatisch eine neue Instanz von Wife angelegt, genau das wollen wir ja nicht -> einfach "= new Wife()" löschen
3. Teste mal so was im main:

```
Man man = new Man();
System.out.println(man.isMarried());
man.wife = new Wife();
System.out.println(man.isMarried());
```
Anm.: schöner wäre natürlich ein void setWife(Wife wife) und ein Wife getWife()


----------



## Illuvatar (5. Apr 2009)

faetzminator hat gesagt.:


> schöner wäre natürlich ein void setWife(Wife wife)



Und ich dachte wir leben in einer zivilisierten Gesellschaft:lol:


----------



## 0x7F800000 (5. Apr 2009)

Illuvatar hat gesagt.:


> Und ich dachte wir leben in einer zivilisierten Gesellschaft:lol:


yoah, wife erstmal richtig schön als attribut des mannes definiert, ohne der referenz in die andere richtung, dass sie ja nicht glaubt sie hätte da irgendwas zu melden 
	

	
	
		
		

		
			




gemein :lol:


----------



## FatFire (5. Apr 2009)

Immer noch besser als ein useKnueppelOn(Wife wife) woraus isMarried = true folgt.


----------



## Spacerat (5. Apr 2009)

Kann es sein, das hier grad' das Thema verfehlt wird? Ging es hier im Prinzip nicht um die initialisierung mit "null" und um die Frage wozu das gut sein soll? Dazu müsste man sich noch mal mit Scopes befassen...[highlight=java]void someMethod() {
  String tmp; // wird hier nicht "String tmp = null;" verwendet gibt's ein Compile Error
  for(int n = 0; n < 10; n++) {
    if(tmp == null) tmp = "";
    tmp += "x";
  }
}[/highlight]Das Beispiel ist zwar nicht das Beste, aber immerhin zeigt es, warum null-Initialisierungen machmal nötig sind.


----------



## 0x7F800000 (5. Apr 2009)

FatFire hat gesagt.:


> Immer noch besser als ein useKnueppelOn(Wife wife) woraus isMarried = true folgt.


Dann wohl eher 

[highlight=Java]
public void getWife(Wife w){
    for(Man m:men){
       if(m!=this){
          if(m.isInterestedIn(w){
              try{
                   useKnueppelOn(m);
              }catch(SelbstWasAufDieFresseGekriegtException e){
                   System.out.println("couldn't get "+w+" , too strong rivals";
                   return;
              }
          }
       }
    }
    //konkurrenz platt!
    this.wifes.add(w);
}

public void isMarried(){
   return wifes.size()>0;
}
[/highlight]
...das wäre so richtig steinzeitmäßig :lol:

Und sonst zur verwendung von null (back to topic):
Einfach wenn man andeuten will, dass etwas nicht da ist, oder noch unbekannt ist:
Beispielsweise bei allen möglichen datenstrukturen, Listen, Bäumen usw. Könnte man null verwenden, um anzudeuten, dass es keine weiteren Listenelemente gibt, d.h. dass man am ende der Liste angekommen ist.
Ich finde es beim Boolean eigentlich schöner, dass man da true, false oder auch "null" zurückgeben kann: beispielsweise bei tests, die eben drei ausgänge haben können - _"ja"_, _"nein"_ und _"ich weiß es nicht, benutzen Sie einen mächtigeren Test"_... 
Oder wenn man bei methoden wie Transform#transform(Point2D p, Pint2D target) durch übergabe von "null" andeuten kann, dass man ein neues exemplar erzeugt haben will, und nicht altes überschreiben will... Ist einfach an vielen Stellen nützlich/unumgänglich.


----------



## UdoKessler (5. Apr 2009)

faetzminator hat gesagt.:


> 1. Bitte an die Konventionen halten, Klassen sollten mit einem Grossbuchstaben anfangen, also z.B. "Wife wife = new Wife()"
> 2. Beim Erstellen von Man wird ja in wife automatisch eine neue Instanz von Wife angelegt, genau das wollen wir ja nicht -> einfach "= new Wife()" löschen
> 3. Teste mal so was im main:
> 
> ...



1. Ok
2. Ja, das habe ich zum kurz testen gemacht. Ausserdem ist das meine erste
eigene Klasse *freu*
Ist denn "Wife wife;" und "Wife wife = null; " das selbe?(..scheint so)

So, habs verbessert:


```
public class Wife {
  int age=0;
  int money=1000;
}
```


```
public class Man {

    int age=0;
    int money=0;
    Wife wife;
    
    public boolean isMarried() {
        return wife != null;   }
    
    public static void main(String[] args) {
        
        Man man = new Man();
        System.out.println(man.isMarried());
       
        man.wife = new Wife();
        System.out.println(man.isMarried());
    }
}
```
Funktioniert einwandfrei 

Hab das Prinzip von null(in dieser Hinsicht) nun verstanden, dankeschön!

Gruß
Udo


----------



## UdoKessler (5. Apr 2009)

Spacerat hat gesagt.:


> Kann es sein, das hier grad' das Thema verfehlt wird? Ging es hier im Prinzip nicht um die initialisierung mit "null" und um die Frage wozu das gut sein soll? Dazu müsste man sich noch mal mit Scopes befassen...



Lass ihnen soch ihren Spaß 
Ich fische mir das Wichtige einfach raus..

Zu Deiner Erklärung:
Habs getestet (someMethod..), wieso gibts hier ein Fehler und
bei meinem Wife wife; in der Klasse Man nicht?


----------



## faetzminator (5. Apr 2009)

UdoKessler hat gesagt.:


> Ist denn "Wife wife;" und "Wife wife = null; " das selbe?(..scheint so)


Grundsätzlich ja, aber in gewissen Situationen musst du explizit "= null" angeben (siehe SpaceRat's Code)


----------



## UdoKessler (5. Apr 2009)

Kurz noch was anderes.. was haltet Ihr von der Formatierung meines
Codes?


----------



## faetzminator (5. Apr 2009)

Ich würde grundsätzlich die Formatter der IDE's verwenden. in Eclipse kannst du z.B. mit [ctrl]+[shift]+[f] den Code formatieren lassen.


----------



## Spacerat (5. Apr 2009)

UdoKessler hat gesagt.:


> Lass ihnen soch ihren Spaß


Aber nur weil heut' Sonntag is'


UdoKessler hat gesagt.:


> Zu Deiner Erklärung:
> Habs getestet (someMethod..), wieso gibts hier ein Fehler und
> bei meinem Wife wife; in der Klasse Man nicht?


Man.wife ist ein Member von Man. Bei "new Man()" wird dort automatisch Platz für die Variable geschaffen, indem ein "null"-Objekt zugewiesen wird. Mein "String tmp" ist eine Methoden-Variable, die am Anfang einen unbestimmten Wert hat (nicht mal "null"). Bei der Deklaration wurde nicht einmal Speicher für die Variable reserviert. Deswegen kommt es auch schon beim 1. Vergleich gegen "null" ("if(tmp == null)") zu diesem Compile-Error.


----------



## UdoKessler (5. Apr 2009)

@faetzminator
Guter "Trick" ! Danke


@Spacerat
Ok, verstehe.


Danke euch allen mal wieder, schön so ein Forum gefunden
zu haben 
Jetzt lese ich mal weiter..


Gruß
Udo


----------



## 0x7F800000 (5. Apr 2009)

UdoKessler hat gesagt.:


> Eclipse Gan*i*mede


Französische Eclipse-version? ???:L


----------



## Marco13 (5. Apr 2009)

Eine Frau wird ja eigentlich erst dadurch zum Wife, dass sie einen Husband hat... Und außerdem... so einfach ist das ganze ja nicht....

```
class Man
{
    private List<Woman> women;

    private boolean isCatholic;

    public void pickUpWoman(Woman woman)
    {
        if (women.size() > 0 && isCatholic)
        {
            throw new PolygamyException("Thou shalst con commit adultery!");
        }
        women.add(woman);
    }

    ...
}
```

Hat jetzt aber auch nicht mehr so viel mit 'null' zu tun....


----------



## faetzminator (5. Apr 2009)

[off] ja klar, es wäre "Woman wife" und nicht "Wife wife" *oops* [/off]


----------



## UdoKessler (5. Apr 2009)

0x7F800000 hat gesagt.:


> Französische Eclipse-version? ???:L



So besser?


----------

