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.
Hi Leute, ich habe eine Frage zu dem folgenden Java Programm:
Java:
public static void main (String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println("Objekt Nummer" + i + "wird jetzt erzeugt");
String name = new String(); //Hierzu meine Frage
}
}
In der Zeile in der ich einen Kommentar eingefügt habe, wird ja explizit ein String Objekt erzeugt. Dieses geschieht insgesamt 10mal (ist ja definiert in der for-schleife).
Meine Frage: Werden jetzt eigentlich insgesamt 10 Objekte im Speicher abgelegt oder nur eins? Wenn es 10 sind, kann ich die dann alle über name ansprechen? Verweist die Referenzvariable name bei jedem Schleifendurchlauf auf ein neues Objekt und die alten werden gelöscht?
Hier meine Frage zu dem Singletonmuster:
Java:
public class Singleton{
private static Singleton instance;
private Singleton(){
System.out.println("Im Konstruktor");
}
public static Singleton getSingleton(){
if(instance == null){
instance = new Singleton();
}
else
System.out.println("Fehler !");
return instance;
}
}
Warum ist hier die Instanzvariable instance mit static deklariert? Warum kann ich stattdessen nich einfach "private Singleton instance;" schreiben?
Sichtbarkeit von Variablen
Gültigkeitsbereich von Variablen
Garbage Collector
Du erzeugst zwar 10 Objekte, die werden aber alle vom Garbage Collector brav freigegeben.
Antwort auf deine Frage, nach der for-Schleife hast du genau 0 String-Objekte.
Bei jedem Schleifendurchlauf wird ein neues String-Objekt erzeugt auf das dann mit name referenziert wird. Die alten Objekte liegen weiterhin im Speicher und können irgendwann vom Garbage-Collector gelöscht werden.
Kannst du nicht. Innerhalb des Blocks (kann man immer prima an den { erkennen) ist ja nur eine Variable definiert, ergo ist auch nur eine für dich da. Es sei denn sie ist in dem Block darüber definiert.
Du kannst mit name immer nur das im aktuellen Schleifendurchlauf erstellte String-Objekt ansprechen, da name nur auf dieses referenziert und auf kein anderes.
D.h. also wenn ich den Code etwas abändere, dann kann ich alle 10 Objekte über name ansprechen?
Java:
public static void main (String[] args) {
String name;
for (int i = 0; i < 10; i++) {
System.out.println("Objekt Nummer" + i + "wird jetzt erzeugt");
name = new String(); //Hierzu meine Frage
}
}
Oh, habe deine 2. dazueditierte Frage jetzt erst gesehen.
Static gehört zu den Grundlagen, und die lernt man am Besten aus der Literatur.
Ich habe Java mit dem "Handbuch der Java-Progammierung" gelernt, die HTML-Version kann man sich unter www.javabuch.de - Das Handbuch der Java-Programmierung kostenlos runterladen.
static sorgt dafür, dass das so deklarierte Objekt / Methode einmalig (je ClassLoader) ist.
Eine static-Methode in einer Klasse kann man zum Beispiel aufrufen ohne das entsprechende Objekt zu initialisieren (also eine Instanz der Klasse zu erzeugen).
Machst du nur eine Variable einer Klasse static greifen alle Klassen auf die selbe Variable zu, anstatt das jede eine eigene Variable in der eigenen Instanz besitzt.
Ok, ich erzeuge z.B. 5x Objekte irgendeiner Klasse, die eine static Variable implementiert hat. Jedes dieser 5 Objekte hat dann jeweils eine static Variable? Ich glaube nicht, sondern es gibt nur eine einzige variable, egal wieviele Objekte ich erzeuge. Ich hoffe, ich habe es nun richtig verstanden...
Wenn die Klassen vom selben Typ sind greifen sie alle auf eine static Variable zu.
Probiers aus, macht Spass.
Deklarier eine Klasse die eine static-Variable hat und lass sie im Konstructor hochzählen.
Damit erschließt sich dann auch gleich ein möglicher Sinn der static-Variablen.
Übrigens: übermässiger Gebraucht davon ist Gift für objektorientiertes Programmieren. Es gilt also abzuwägen ob eine static-Variable nötig uns sinnvoll ist.
Ich habe es eben mal ohne static durchlaufen lassen und habe vom Compiler diese Fehlermeldung erhalten:
non-static variable instance cannot be referenced from a static context
if(instance == null){
^
Diese Fehlermeldung erhalte ich auch, wenn ich bei der publicmethode das static entferne. Vielleicht denke ich jetzt einfach zu kompliziert, aber irgendwie verstehe ich das nicht ganz...
du hast eine Methode static deklariert. Nimm dir einen Moment Zeit und denk darüber nach was das heisst. Diese Methode kann immer und überall, ohne dass die umliegende Klasse initialisiert wurde, angesprungen werden.
Erkennst du vielleicht warum deine main-Methode deshalb static sein muss?
So, und irgendwo in dieser static-Methode greifst du auf eine Objekt/eine Variable zu die NICHT static ist und sich außerhalb der Methode befindet. Das kann nicht funktionieren. Verstehst du warum? Weil das worin die Variable eingebettet ist, nämlich die Klasse, unter Umständen nicht initialisiert ist, der Variable fehlt der Kontext/das worin sie eingebettet ist.
Aus diesem Grund können aus einem statischem Kontext/einer statischen Methode, nur Variablen/Objekte angesprochen werden die selbst auch statisch sind. Denn dann sind sie einmalig und existieren unabhängig der Klasse in der sie stehe.
Das heißt also wenn ich private static Singleton instance; sage, dann muss ich auch public static Singleton getSingleton() sagen, sonst klappt das nicht.
Also wäre bspw. private Singleton instance; und public static Singleton getSingleton() falsch...
..genauso wie...
private static Singleton instance; und public Singleton getSingleton() falsch...
Eine Frage habe ich nochmal zu dem Thema. Worin besteht eigentlich genau de Vorteil, wenn ich eine Referenzvariable mit null inistailisiere, also bspw.
Java:
public class Singleton{
private static Singleton instance = null;
private Singleton(){
System.out.println("Im Konstruktor");
}
public static Singleton getSingleton(){
if(instance == null){
instance = new Singleton();
}
else
System.out.println("Fehler !");
return instance;
}
}
oder in einem solchen Beispiel
Java:
public class Test{
private ref1 = null
....
}
Was bringt es mir, hier mit der null-Referenz zu arbeiten?
null heißt nur, dass die Referenz auf kein Objekt bzw. irgendwo hin ins Nichts zeigt.
Java:
public class Test {
private Object ref = null;
}
ist das Gleiche wie
Java:
public class Test {
private Object ref;
}
Ein Objekt wird anfangs immer mit null initialisiert. Bei primitiven Datentypen gilt das allerdings nicht, die werden mit 0 bzw. bei boolean mit false initialisiert.
es sein aber angemerkt, dass, sobald die Initialisierung der "instance" Variable nicht von der Runtime gemacht wird, das SingletonPattern nicht threadsafe ist. Also besser die static Variable direkt mit new Class() initialisieren. Die Abfrage auf null fällt dann auch weg. Zusätzlich die getInstance()-Methode noch syncronized...
Ok danke ! Um nochmal festzuhalten. Die Anwendung der "null Referenz" bringt mir als Entwickler also keine erweiterten Programmiermöglichkeiten / Programieroptionen, sondern dient nur dazu, um den Quellcode besser lesbar zu machen?