Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hallo,
ich bin ein neuling bei der Java-Programmierung. Arbeite gerade mit dem Buch Java 6 von Dirk Louis und Peter Müller. Es gibt dort einen Sachverhalt, den ich noch nicht verstehe, weil er nicht umfangreich erklärt ist oder weil ich die Erklärung schlicht nicht verstehe...
Es geht um das Schlüsselwort new , welches manchmal nicht verwendet wird.
Es soll hier ein Objekt der Klasse Console erzeugt werden, um Schreibarbeit zu sparen, also wegen (System.console().printf(); )
Hierbei wird das new jedoch weggelassen, also kein "Console cons = new System.console();"
und ich frage mich warum das so ist, wo doch alle Instanzen mit new erzeugt werden müssen bei der ooP.
Nicht ganz: es soll eine Referenz auf ein Objekt vom Typ [JAPI]Console[/JAPI] erzeugt werden. Die Erzeugen des Objekts selbst fand in der Klasse [JAPI]System[/JAPI] statt. Mit
Code:
System.console()
wird die statische Methode
Code:
console()
in der Klasse [JAPI]System[/JAPI] aufgerufen, die ein (vorher intern mit new erzeugtes) Objekt zurükgibt.
Das roteingefärbte ist wohl das entscheidende. Heißt das ich muss immer vorab wissen dass das Object vorher ezeugt wird? Oder gibt es da irgendeinen Trick, wie man erkennen kann, wann man eine Objekt selber erzeugt und wann nicht.
Da steht, dass console() eine Methode ist, die ein Object vom Typ Console zurückliefert. Wenn du eine Methode aufrufst, musst du nie new verwenden. new wird nur beim Aufruf eines Konstruktors verwendet. Also mit anderen Worten, hinter new steht immer ein Klassenname, aber niemals ein Methodenaufruf.
Das roteingefärbte ist wohl das entscheidende. Heißt das ich muss immer vorab wissen dass das Object vorher ezeugt wird? Oder gibt es da irgendeinen Trick, wie man erkennen kann, wann man eine Objekt selber erzeugt und wann nicht.
Bei Bibliotheksklassen stehts in der API, wie Du ja schon gemerkt hast.
Bei eigenen Klassen gilt: grundsätzlich muss ich davon ausgehen, das ich selbst ein neues Objekt erstellen muss. Ich kann dies aber (wie bei System.console()) in eine "Service-Methode" auslagern. Das hat mehrere Vorteile:
- ich kann allen Programmteilen das selbe Objekt geben (es gibt also nur ein einziges Objekt im gesamten Programm, wie im Beispiel)
- ich kann eine abgeleitete Klasse zurück geben, ohne dass ich die Programmstellen, die dieses Objekt verwenden ändern muss.
Um die eigentlich von Timothy Truckle bereits ausreichend geschilderte Situation nochmals näher zu beschreiben:
Die Klasse "System" unterliegt nicht dem klassischen Prinzip der OO. Es handelt sich hierbei um eine statische Klasse. Dabei handelt es sich um eine Klasse die nicht durch das objektorientierte System beeinflusst/beeinschränkt wird.
Das hat jedoch den Nachteil der von dir beschriebenen Verwirrung sowie das von dieser Klasse nur eine einzige Instanz existieren kann. Jedoch mit dem Vorteil das von überall aus darauf zugegriffen werden kann.
Erkennen ob du die jeweilige Methode mit dem Klassennamen aufrufen kannst oder ein neues Objekt erstellen musst, kannst du daran erkennen ob die Methode das Stichwort "static" beinhaltet.
Statische Methoden können auch direkt aufgerufen vom jeweiligen Objekt
Java:
System system = new System();
system.console();
Der Compiler kreidet dass dann als Warnung an, deine IDE wird dich also darauf hinweisen dass es eine static-Methode ist, das Programm läuft aber trotzdem.
Viele Neulinge kommen an dieser Stelle auf die Idee, dass das doch recht praktisch ist -> Das ist echt fies von den Entwicklern der JavaLib denn die sind nicht immer gerade ein gutes Vorbild.
Also komme nicht auf die Idee ab sofort static zu verwenden. Vergiss es am besten ganz schnell wieder.
um Deine Verwirrung mal zu komplettieren, muss ich Network widersprechen. Deine eigentliche Frage, wann Du ein new benötigst und wann nicht hat nicht direkt etwas mit statischen Methoden zu tun.
Erstmal vorweg, es ist nicht falsch, auf statische Methoden kannst Du immer zugreifen, ganz ohne je ein new Aufgerufen zu haben. Aber das ist nur die berühmte halbe Wahrheit (oder 21).
Es gibt mindestens vier verschiedene Gründe, wann Du keinen new-Operator aufrufen musst:
Primitive Datentypen
Statische Methoden
Strings
Extern erzeugte Referenzen
Primitive Datentypen hast Du bestimmt schon kennengelernt (fangen immer mit einem Kleinbuchstaben an), gehe ich hier nicht näher drauf ein.
Die statischen Methoden wurden bereits ausgeführt und hier gilt es wirklich, dass man wissen sollte wann man die verwendet. Sonst sind die einfach unsauber und führen zu miserablen Code, der auf die Vorteil der Objekt Orientierung verzichtet.
Strings sind etwas ganz besonder Hässliches in Java - und vielen anderen Sprachen. Um den Komfort zu erhöhen werden hier statische Konstruktoren verwendet, schreibst Du
Code:
"Ein String"
wird intern dafür gesorgt, dass hier ein Objekt vom Typ String verwaltet wird. Du könntest zwar auch
Code:
new String("Ein String")
schreiben, dies wäre aber alles andere als guter Stil, da hier zwei mal für ein neues Objekt gesorgt wird. Wie gesagt, eine einzige Ausnahme und deshalb nur der Vollständigkeit wegen erwähnt.
Das andere (ob statisch oder nicht) sind Methoden, die Dir eine Referenz zurückgeben. Jede Methode hat immer einen Rückgabewert. Bei void ist dieser quasi leer und wird nicht weiter berücksichtigt, aber sonst steht da ja immer der Datentyp, den die Methode zurück gibt.
Hierfür gibt es verschiedene Gründe, zum Beispiel kann es sein dass Du etwas berechnen möchtest, das einen komplexen Datentypen hat. Sagen wir mal, Du möchtest mit Punkten rechnen, die eine X und Y Komponente haben. Der Datentyp sieht vielleicht so aus:
Code:
public class Coordinate {
private int x;
private int y;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
// ... Getter und Setter
}
Möchtest Du jetzt Koordinaten addieren oder Ähnliches, dann kann es sein dass eine Methode dazu einfach ein neues Objekt erzeugt und dieses zurück gibt:
Code:
public Coordinate add(Coordinate first, Coordinate second) {
// Summe der Koordinaten berechnen
int resultX = first.getX() + second.getX();
int resultY = first.getY() + second.getY();
// Neues Objekt erzeugen, in welche das Ergebnis geschrieben wird
Coordinate result = new Coordinate(resultX, resultY);
return result;
}
Hier würdest Du vor dem Aufrufer das "new" verbergen. Der Aufrufer der Methode bekommt einfach eine Referenz auf ein (neu erzeugtes) Objekt.
Ganz typische Fälle sind eben solche Berechnungen, die ein Objekt erzeugen. Es gibt aber Caches und Pools, das heißt hier werden mehrere Objekte verwaltet und wiederverwendet (ein komplexes Thema, weshalb man hier einfach fertige Lösungen verwendet). Hier werden Objekte einfach "auf Vorrat" angelegt und immer wenn eins benötigt wird, sucht man ein aktuell freies und gibt dieses zurück. Das sparrt dann die Zeit, die die Objekterzeugung (eben der Aufruf von new) benötigt. Hier kannst Du Dir einfach vorstellen, dass der Speicher schon reserviert wurde, genau das entfällt entsprechend.
@TO
um auf die frage "warum kein new?" direkt und ohne weitere verwirrungen zu antworten : weil du bei "System.console()" eben KEIN neues objekt erzeugst sondern dir nur eine referenz auf ein bereits bestehendes objekt
sowas nennt man "statische utility methoden" ... und das sind eigentlich fast alle klassen in java.lang ...
du hast also eine klasse ... z.b. System ... und diese bitet dir statische methoden an ... z.b. console() ... die dir eine referenz auf ein objekt eines bestimmten types zurückgeben ...
NEW wird NUR verwendet wenn du auch wirklich explizit ein neues objekt über einen konstruktor erzeugen willst ... also "new Object()" oder "new ArrayList<Set<Class<?>>>()" ...
Ein Aspekt wurde noch vergessen (ist für Anfänger vielleicht wichtig):
Es gibt keine "Regel" wann ein Objekt mit new erzeugt werden muss oder ob unter Umständen eine sogenannte statische Factory-Methode eine Referenz auf ein Objekt zurückliefert. Hängt von der verwendeten Bibliothek, den Umständen und den Sackläusen den zuständigen Entwicklers ab.
Die Console ist insofern ein Spezialfall, weil sie ein "eindeutiges, einmaliges" Ding repräsentieret (das kleine schwarze Bildschirmfenster, in dem man mit java Klassenname ein Programm starten kann). Es würde ziemliches Chaos anrichten, wenn die Programmierer mit new immer neue solche Konsolen erzeugen könnten - deshalb haben sich die Programmierer bei Sun damals entschlossen, diese über System.console() verfügbar zu machen.