"Java.util.Scanner(System.in).nextLine" wo ist die Instanz? Wie schließen?

Hallo.
Ich habe eine Frage zu folgendem kleinem Programm:

public class SmallConversation{

    public static void main(String[] args){
	
	System.out.println("Moin! Wie heißt denn du?" );
	String name = new java.util.Scanner(System.in).nextLine();
	System.out.printf("Hallo %s. Wie alt bist du?%n", name);
	java.util.Scanner sc = new java.util.Scanner(System.in);
	int age = sc.nextInt();
	System.out.printf("Aha, %s Jahre , das ist ja die haelfte von %s.%n", age, age * 2);
	System.out.println("Sag mal, was ist deine lieblings fließkommazahl?" );
	java.util.Scanner sc1 = new java.util.Scanner(System.in);
	double value = sc1.nextDouble();
	System.out.printf("%s? Aha, meine ist %s.%n", value, Math.random() * 100000 );


    
    sc.close();
    
	sc1.close();
	
	
}

Ich habe es abgeändert weil ich wissen wollte ob ich selbständig ohne nachzusehen eine Instanz von „Scanner“ erzeugen kann.
Jetzt habe ich aber das Problem, dass ich in der Zeile

String name = new java.util.Scanner(System.in).nextLine;

nichts mit „close();“ schließen kann.
Ich habe ja selbst keine Instanz von Scanner erzeugt, und in „name“ wird ja nur die „Benutzer-Eingabe“ gespeichert.

Alle anderen Instanzen wie z.B „sc“ und „sc1“ kann/ soll ich am ende ja schließen.

Ich erhalte zwar nur eine"Warnung" aber auch diese soll ja beachtet werden.

Warning: Resource leak <unassigned Closeable value> is never 
closed.

Kann mir da evtl. jemand einen Hinweis geben bzw mir erklären warum ich eine WARNUNG erhalte.

Ich hoffe, dass man meine Frage versteht und danke im voraus.
Grüße

Nun. Mit

java.util.Scanner sc = new java.util.Scanner(System.in);

wird ja eine Instanz erstellt, die auch geschlossen werden kann. Diese eine Instanz könnte für alle Eingaben verwendet werden. Ganz am Anfang erstellen. Ganz am Ende schließen. (Geschickter mit „try-with-resources“, aber das wäre ein nächster Schritt…)

Hallo

Entweder habe ich meine Frage falsch gestellt oder…
Das „sc“ und „sc1“ Instanzen der Scanner Klasse sind ist nur bewusst.
Mir geht es im speziellen um die Zeile:

String name = new java.util.Scanner(System.in).nextLine();

Wo ist da die Instanz? Ich habe allerdings gelesen, Zitat:
… falls ein Objekt von Typ closeable dahintersteckt, wie ein writer, sollte mit close() der Scanner geschlossen werden, der das close() zum closeable weiterleitet. (Ab hier Wichtig:) Beim String ist das nicht nötig (also obige Zeile), und bei file schließt der Scanner selbständig.

Warum ist es bei String nicht nötig? Das muss doch einen Grund haben.
Auch wenn es eine Hintergrund Schließung sein sollte würde ich diese gern verstehen.
Und wie gesagt, habe ich die Scanner „sc“ und „sc1“ eingständig umgeschrieben. Vorher waren auch diese Zeilen wie die obige, nur eben mit „int“ & „double“

Ich hoffe man versteht jetzt was ich meine.

Danke und Grüße
Steffen

Instanzen erstellt man durch…? Richtig! Durch verwenden des Schlüsselwortes new vor dem Klassennamen der zu instanziierenden Klasse.
Normalerweise räumt der Garbage Collector nicht mehr benötigte/benutzte Objekte aus dem Speicher.
Da nach Deiner obigen Anweisung keine Referenz auf das Objekt im Speicher verweist, sollte der GC diese auch wegräumen.
Ich habe bisher nie einen Scanner geschlossen. Eine Fehler-/Warnmeldung, wie Du sie oben gezeigt hast, habe ich bisher auch nicht gesehen. Vielleicht eine Einstellung in Deiner IDE?

Und: Du brauchst nicht immer eine neue Instanz von Scanner erzeugen

Aber in der API-Doku von Scanner gibt es brauchbare Beispiele.
https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html

String name = new java.util.Scanner(System.in).nextLine();
              |----------- ^ da ^ ------------|

Die Instanz wird erstellt, dann wird auf dieser Instanz nextLine aufgerufen, und danach landet die Instanz im Müll - allerdings ohne vorher geschlossen zu werden. Und das ist genau das, was die Warnung besagt.

(Ab hier Wichtig:) Beim String ist das nicht nötig (also obige Zeile), und bei file schließt der Scanner selbständig.

Das bezieht sich vermutlich auf Scanner (Java Platform SE 8 ) : Man kann auch einen Scanner mit

Scanner s = new Scanner("Lies diesen Text");
System.out.println(s.next()); // Gibt 'Lies' aus
System.out.println(s.next()); // Gibt 'diesen ' aus
System.out.println(s.next()); // Gibt 'Text' aus

verwenden, und der muss nicht geschlossen werden.

Ansonsten sollte ein Scanner normalerweise schon geschlossen werden, wenn etwas „schließbares“ dahinter steckt. Wobei System.in so gesehen auch wieder was besonderes ist: Das sollte normalerweise nicht geschlossen werden, aber wenn man den Scanner am Anfang erstellt, und am Ende schließt, ist das OK.

1 Like

Klar erzeugst du eine Instanz, da steht ja new :wink: