# Warnung in Eclipse: unassigned closeable value



## Sw4rls (30. Sep 2012)

Hallo,

ist mein erster Post hier. Ich fange gerade an, mir Java selbst beizubringen. Ich bin also noch ziemlicher Anfänger, aber bringe schon kleine Miniprogrämmchen zustande. Ich benutze Eclipse und bekomme eine Warnung bei folgendem Code:


```
public class Circle
{
	
	public static void main(String[] args)
	{
		
		circleArea();
		
	}
	
	public static void circleArea()
	{
		
		System.out.println("Bitte Radius des Kreises angeben:");
		double radius = new java.util.Scanner(System.in).nextDouble();
		System.out.println("Die Flaeche des Kreises betraegt");
		System.out.println(2 * radius * radius * Math.PI);
		
		
	}
}
```

Die Warnung ist für diese Zeile:
	
	
	
	





```
double radius = new java.util.Scanner(System.in).nextDouble();
```
 und lautet:
- Resource leak: '<unassigned Closeable value>' is never closed

Was habe ich falsch gemacht? Wie muss ich den Code korrigieren, damit die Warnung nicht mehr erscheint?

Danke im Voraus für hilfreiche Antworten.

Sw4rls


----------



## kaetzacoatl (30. Sep 2012)

schließ das Project mal und lad es dannm mit
neu gestartetem eclipse neu. Da ist kein Fehler.


----------



## Fant (30. Sep 2012)

Die Meldung besagt einfach, dass du den Scanner besser mit .close() schließen solltest.
Die Warnung kannst du bei deinem kleinen Mini-Programm aber auch ruhig ignorieren,


----------



## Ark (30. Sep 2012)

Fant hat gesagt.:


> Die Warnung kannst du bei deinem kleinen Mini-Programm aber auch ruhig ignorieren,


Genau! Gewöhnen wir uns gleich zu Beginn einen schlechten Stil an! 

@Sw4rls: AutoCloseable (Java Platform SE 7 ) und New Java 7 Features: The Try-with-resources Language Enhancement

Ark


----------



## Fant (30. Sep 2012)

Ark hat gesagt.:


> Genau! Gewöhnen wir uns gleich zu Beginn einen schlechten Stil an!



Ja, du hast ja recht ... aber wenn jemand gerade mit dem Programmieren anfängt, dann gibt es vermutlich erst mal wichtigeres, dass es zu verstehen gilt.


Übrigens: Die Formel zur Berechnung der Kreisfläche ist falsch


----------



## Manello (1. Okt 2012)

> Ja, du hast ja recht ... aber wenn jemand gerade mit dem Programmieren anfängt, dann gibt es vermutlich erst mal wichtigeres, dass es zu verstehen gilt.


Es gibt wichtigeres? Na dann, gut Nacht wenn du schon so anfängst, wie werden die großen Programme mal aussehen? Ordnung und Leserlichkeit ist dass wichtigste, und wenn man ganz viele kleine Fehler Ignoriert, kommt am ende auch ein großes Problem raus.


----------



## Sw4rls (1. Okt 2012)

Erst mal danke für die Antworten. Leider werde ich aus den beiden Links nicht direkt schlau. Ich verstehe, dass man den Scanner wieder schließen sollte, wenn er nicht mehr gebraucht wird. Aber wie gebe ich das jetzt syntaktisch an?

Also mein Code sieht jetzt so aus:


```
import java.lang.Math;

public class Circle implements AutoCloseable
{
	
	public static void main(String[] args) throws Exception
	{
		
		circleArea();
		
	}
	
	public static void circleArea()
	{
		
		System.out.println("Bitte Radius des Kreises angeben:");
		double radius = new java.util.Scanner(System.in).nextDouble();
		System.out.println("Die Flaeche des Kreises betraegt");
		System.out.println(radius * radius * Math.PI);
		
		
	}

	public void close() throws Exception
	{
		
		System.out.println("Die Fläche des Kreises ist berechnet.");
		
	}
}
```
 (Ja, ich habe die Formel auch gleich verbessert )

Ich habe noch nicht ganz verstanden, wie das genau funktioniert. Vielleicht kann mir jemand das möglichst einfach erklären (oder zumindest sagen, was in meinem code noch fehlt).


----------



## Fant (1. Okt 2012)

Damit du den Scanner wieder schließen kannst, musst du ihn zuvor einer Scanner-variablen zuweisen. Etwa so:


```
Scanner scanner = new Scanner();
// ( mache was mit dem Scanner)
scanner.close();
```


----------



## xehpuk (1. Okt 2012)

Die Warnung sagt nur aus, dass du einen von vielen Eclipse-Bugs entdeckt hast. 
[JAPI]System#in[/JAPI] sollte man wohl nicht schließen.


----------



## Ark (1. Okt 2012)

xehpuk hat gesagt.:


> Die Warnung sagt nur aus, dass du einen von vielen Eclipse-Bugs entdeckt hast.


Und wo ist da jetzt der Fehler? ???:L

Ark


----------



## xehpuk (1. Okt 2012)

Man wird gewarnt, dass man den Scanner nicht geschlossen hat, welcher 
	
	
	
	





```
System.in
```
 wrappt.
Allgemein braucht man ihn doch nicht zu schließen, wenn er per [JAPI]Scanner#Scanner(java.io.InputStream)[/JAPI] erzeugt wurde. Dabei wird ja kein neuer Stream geöffnet oder dergleichen. Der unterliegende Stream muss lediglich irgendwann geschlossen werden. Es sei denn, es handelt sich um 
	
	
	
	





```
System.in
```
. Oder habe ich etwas verpasst?


----------



## Ark (1. Okt 2012)

xehpuk hat gesagt.:


> Oder habe ich etwas verpasst?


Wie man's nimmt. Jedenfalls würfelst du gerade viele verschiedene Sachen durcheinander. 



xehpuk hat gesagt.:


> Allgemein braucht man ihn doch nicht zu schließen, wenn er per [JAPI]Scanner#Scanner(java.io.InputStream)[/JAPI] erzeugt wurde. Dabei wird ja kein neuer Stream geöffnet oder dergleichen. Der unterliegende Stream muss lediglich irgendwann geschlossen werden.


Das ist zwar richtig, aber hier gar nicht von Belang. Der Parser orientiert sich nur an AutoCloseable, und da Scanner dieses Interface implementiert, kommt eine entsprechende Warnung. Der Scanner hätte genausogut auch mit [c]new Scanner(new File("foo.txt"))[/c] erzeugt werden können, da würde dein Argument nicht mehr ziehen. 

Und außerdem hat das noch nicht einmal was mit Eclipse zu tun. Wie gesagt, es liegt an AutoCloseable beim Scanner, und dafür kann Eclipse nichts.



xehpuk hat gesagt.:


> Es sei denn, es handelt sich um
> 
> 
> 
> ...


Nicht nur. Es hätte auch jeder x-beliebige andere InputStream sein können, der _eigentlich_ nicht geschlossen werden muss. Aber der Parser kann nicht entscheiden, wann es notwendig ist und wann nicht. Das kann man als Entwickler nur der Dokumentation entnehmen. (Und selbst dann wird es wohl kaum falsch sein, den Datenstrom sauber zu schließen.)

Ark


----------



## xehpuk (2. Okt 2012)

Ark hat gesagt.:


> Das ist zwar richtig, aber hier gar nicht von Belang. Der Parser orientiert sich nur an AutoCloseable, und da Scanner dieses Interface implementiert, kommt eine entsprechende Warnung. Der Scanner hätte genausogut auch mit [c]new Scanner(new File("foo.txt"))[/c] erzeugt werden können, da würde dein Argument nicht mehr ziehen.


Und genau das ist das Problem. Das wurde einfach schlecht/fehlerhaft implementiert. Man hätte zwischen den Konstruktoren unterscheiden können.



Ark hat gesagt.:


> Und außerdem hat das noch nicht einmal was mit Eclipse zu tun. Wie gesagt, es liegt an AutoCloseable beim Scanner, und dafür kann Eclipse nichts.


Das hat sehr wohl etwas mit Eclipse zu tun. Diese Warnung kommt von Eclipse und seinem Parser, nicht von 
	
	
	
	





```
javac
```
.



Ark hat gesagt.:


> Aber der Parser kann nicht entscheiden, wann es notwendig ist und wann nicht.


In diesem Fall wäre es gegangen. In Fällen, in denen das nicht gegangen wäre, hätte er einfach gar nichts sagen sollen. Für mich ist das einfach eine falsche Warnung.


----------



## Ark (2. Okt 2012)

xehpuk hat gesagt.:


> Und genau das ist das Problem. Das wurde einfach schlecht/fehlerhaft implementiert. Man hätte zwischen den Konstruktoren unterscheiden können.


Hm, und wie genau? Mit Annotations? Mit Interfaces (=jetzige Lösung) stelle ich mir das jedenfalls etwas schwierig vor …



xehpuk hat gesagt.:


> Das hat sehr wohl etwas mit Eclipse zu tun. Diese Warnung kommt von Eclipse und seinem Parser, nicht von
> 
> 
> 
> ...


Ich habe mir gerade mal den entsprechenden Abschnitt der Sprachspezifikation durchgelesen, und da fand ich jetzt keinen Hinweis darauf, wie so etwas vom Parser zu behandeln ist. Insofern stimmt es natürlich, dass dieses Verhalten Eclipse-spezifisch ist. Aber es ist, wenn ich das richtig verstanden habe, auch kein fehlerhaftes Verhalten. Wenn es dich stört, kannst du die Warnung abschalten (sollte gehen).



xehpuk hat gesagt.:


> In Fällen, in denen das nicht gegangen wäre, hätte er einfach gar nichts sagen sollen.


Und da ist das Problem: Finde einen Algorithmus, der für alle Java-Quelltexte in endlicher Zeit und mit endlichem Speicher korrekt entscheiden kann, ob "das gegangen wäre" oder nicht.

Ich bin übrigens der Meinung, dass in diesem Fall der Fehler eher in den angebotenen Konstruktoren von Scanner zu suchen ist. Meiner Meinung nach hätte es für jeden Konstruktor nur eine für alle Konstruktoren identische Möglichkeit geben dürfen, die Eingabe festzulegen, und zwar über CharSequence. Dann bräuchte ein Scanner auch kein Closeable, geschweige denn ein AutoCloseable.

Ark


----------



## xehpuk (2. Okt 2012)

Ark hat gesagt.:


> Mit Interfaces (=jetzige Lösung) stelle ich mir das jedenfalls etwas schwierig vor …


Hmm, hier wird wohl das Problem sein. Man müsste im Prinzip zwischen echten Ressourcen und Wrappern unterscheiden.
Hierbei ist eigentlich auch nur der "richtige" Stream zu schließen:

```
new BufferedInputStream(new FileInputStream("…"));
```
Am Ende schließt man diesen aber über den Wrapper, weil man in der Regel keine Referenz mehr hat.

Ist in der Tat also nicht leicht zu machen. Ich finde dieses Verhalten jedenfalls problematisch, wenn man keine einzige Warnung im Code haben will. So muss man diese im Allgemeinen hilfreiche Warnung wegen der einen Falschmeldung ausstellen.



Ark hat gesagt.:


> Wenn es dich stört, kannst du die Warnung abschalten (sollte gehen).


Ist nicht nötig, weil ich durch die drastische Performanceeinbuße bei Juno umgestiegen bin. NetBeans hat wiederum natürlich auch seine Macken …


----------



## Sw4rls (2. Okt 2012)

Hm, also lautet der Konsens nun, dass ich den ursprünglichen Code also ohne in schlechtem Stil zu schreiben, stehen lassen kann?

Jedenfalls bekomme ich die Warnung, was ich auch versuche, nicht weg. Und da ich nicht Tage damit verbringen will, werde ich erst mal weiter lernen und mich des Problems annehmen, wenn ich später nochmal darauf treffe.

Danke jedenfalls für alle Antworten!


----------



## hüteüberhüte (2. Okt 2012)

Netbeans zeigt übrigens keine Fehlermeldung.

Guter Stil wäre in diesem Fall:


```
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Bitte Radius des Kreises angeben:");
        double radius = Double.parseDouble(reader.readLine());
        System.out.println("Die Flaeche des Kreises betraegt: " + radius * radius * Math.PI);
```

+ throws IOException


----------



## Sw4rls (2. Okt 2012)

Ok, also wenn ich den Code so schreibe:


```
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.Math;

public class Circle
{
	
	public static void main(String[] args) throws IOException
	{
		
		circleArea();
		
	}
	
	public static void circleArea() throws IOException
	{
		
	    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
	    System.out.println("Bitte Radius des Kreises angeben:");
	    double radius = Double.parseDouble(reader.readLine());
	    System.out.println("Die Flaeche des Kreises betraegt: " + radius * radius * Math.PI);
		
	}
}
```

gibt mir Eclipse weder Warnung noch Fehler aus. So werde ich es also lassen. Vielen Dank!


----------



## hüteüberhüte (2. Okt 2012)

"unassigned Closeable value" bedeutet ja etwas wie "Nicht-zugewiesene schließbare Variable wird nicht geschlossen"

Finde die Warnung auch unnötig. IDE s sind eben auch nicht fehlerfrei

Am Besten wärs, du würdest dich nicht weiter um solche Meldungen kümmern und mit OOP weitermachen (eigene Kreis-Klasse schreiben)


----------



## Sw4rls (2. Okt 2012)

Mein Ansinnen ist eigentlich, ein Programm zu schreiben, dass einem Körper ausrechnet und später vielleicht Optimierungsmöglichkeiten aufzeigt.

Also So was wie:

- Diese Zylinderförmige Verpackung hat das und das Volumen.
- Wenn Ich ein bestimmtes Volumen haben möchte, wie sollten Radius und Höhe dann am besten aufgeteilt sein, damit ich möglichst wenig Material brauche?
- Auch anders herum: Wenn ich nur bestimmtes Material zur Verfügung habe, wie forme ich dann den Zylinder um möglichst viel Volumen zu bekommen?

Bis dahin hab ich noch ein bisschen Weg, aber ich denke das sollte machbar sein.
Jetzt wird es aber doch ein bisschen Off-Topic.


----------



## hüteüberhüte (2. Okt 2012)

Mit anderen worten, formel für radius, höhe und volumen ableiten und minimum bestimmen. Radius und höhe stehen ja immer im denselben verhältnis.[/OT]

Gesendet von mit Tapatalk 2


----------

