Richtig. Aber das ist kein Grund für den Compiler zu meckern. Eben für soetwas sind Schleifenbedingungen da. Sie können ausgeführt werden, müssen aber nicht (und wenn sie ausgeführt werden, dann eben solange, bis der Wert false ist, oder man "ausbricht").
sicher geht er nicht in die schleife, aber das sysout steht ja hinter der Schleife.
Ist so als wenn ein Kasten Wasser hinter deinem Auto steht und du überprüfst erst, ob du den Schlüssel vom Auto in der Tasche hast. Hast du nicht, aber den Kasten Wasser kannst trotzdem in deine Wohnung tragen.
genau. ignorieren ist vllt etwas hart. er prüft die bedingung vor jedem durchlauf und nachdem diese schon beim ersten durchlauf false liefert wird die schleife beendet bevor sie überhaupt angefangen hat
eigentlich sollte der compiler auch ohne das final erkennen können das (x--) ein unreachable statement ist da er ja weis das zwischen dem initialisieren von x mit dem wert 12 und dem prüfen ob x kleiner als 10 ist halt NICHTS mehr ist das x verändert
ich denke viel eher das der compiler nicht meckert weil er nur die while() als solches ansieht und nicht prüft ob die bedingung überhaupt jemals true werden kann denn das ist die aufgabe der Runtime und nicht des compilers
was das mit dem final angeht
xehpuk hat nur teilweise recht
der compiler weis durch das final nicht automatisch das die bedingung niemals erfüllt wird
dies bekommt er nur raus weil er mit final deklarierte referenzen anders behandelt
er stellt dann beim compilen der while() fest das x verändert werden MUSS um die bedingung zu erfüllen was aber durch FINAL nicht möglich ist
eigentlich müsste er dann nicht nur einen unreachable statement error werfen sondern auch einen illegal statement error da (x--) eine veränderung von x ist und dies laut definition von FINAL unzulässig wäre
da er diese anweisung aber bereits mit dem error kennzeichnet das sie sowieso nicht erreichbar ist wird dies verschluckt
Darum ging es mir nicht, das meinte ich gar nicht. Es ging darum, dass der Compiler meckert, weil die Schleife nie betreten werden kann. Es gibt also auch ohne
Code:
x--;
Gemecker.
Gemecker der gleichen Sorte würds auch hier für das letzte Statement geben, weil die Schleife nie verlassen wird:
Java:
finalint x =12;while(x >10){// x--;}System.out.print(x);
eigentlich sollte der compiler auch ohne das final erkennen können das (x--) ein unreachable statement ist da er ja weis das zwischen dem initialisieren von x mit dem wert 12 und dem prüfen ob x kleiner als 10 ist halt NICHTS mehr ist das x verändert
Und was wenn da noch weitere Threads laufen, die unter Umständen das x "zufälligerweise" vor dem Betreten der Schleife verändern würden ? Oder dass das x über Sockets oder ähnliches verändert wird ? Das kann und darf der Compiler NICHT ausschließen. Bei final ist das was anderes, da er da zu 100% sicher ist, dass das x nicht mehr verändert werden kann.
Das stimmt. Aber nach eurer Denkensweise, müsste der Compiler genauso bei so etwas meckern (pseudocode):
Java:
publicclassTest{int x =12;publicTest(){}//irgend ne Methode, in der allerdigs das x nicht verändert wird.{.....while(x <10){//inhalt}}}
Da wird das x doch auch nirgendswo verändert, also müsste die while() auch als unreachable code markiert werden, oder ? Also nach eurer Denkensweise. Soll der Compiler noch extra überprüfen, ob die Variable irgendwo übergeben wurde, oder ob andere Threads ggf. eine Referenz auf das Objekt haben und die Variable verändern oder wie ?
Ein Check bei (non-final) Instanzvariablen ist wohl zu weitgehend für den Compiler, weil er eben sicherstellen müsste, dass der Wert der Variable nirgendwo verändert werden kann.
Variablenübergabe ist hier ja kein Thema wegen "call by value".
Abgesehen von Reflection, (in diesm fall nicht vorhandenen) Setter oder internen Methoden, kann das x noch von JNI-Calls manipuliert werden (mittels JNI und Reflection ist es auch möglich finale Variablen zu ändern).
Auf die schnelle würde mir hier nur bytecodemanipulation einfallen, um dieses x zu verändern, sodass es der Compiler nicht mitbekommt.
In diesem fall ist das kein Thema, das ist schon klar, aber wir können doch nicht erwarten, dass der Compiler guckt, ob es sich bei den Variablen um Call By Value oder Call By Reference handelt, dann noch überprüft ob es getter, setter, referenzen auf das Objekt gibt und sonst etwas.
Zu den Reflections und JNI-Calls kann ich jetzt nichts sagen, da ich auf diesem Gebiet ehrlich gesagt gar keine Ahnung habe.
Worauf ich eigentlich hinaus wollte: Meiner Meinung nach, sollte der Compiler bei solchen Fällen gar nicht meckern (auch bei final nicht - sehe Post von Tomate_Salat ). Als Unreachable code markiert gehört für mich nur Code der hinter einem Return (ohne finally und so etwas) noch eusgeführt werden sollte. Was Variablen und betreten der Schleifen aufgrund von Werten angeht, sollte der sich davon fern halten
Java kennt an sich kein wirkliches Call by Value oder Call by Reference. Es wird normal lediglich die Speicheradresse des Objektes übergeben. Weswegen soetwas auch keine Nachhaltigen Auswirkungen hat:
aber das ist ein anderes Thema (kleiner Tipp: um solche Logikfehler zu vermeiden: Parameter einfach final machen und in der IDE die Warnung einstellen).
Das der Compiler bei final meckert ist OK und richtig so. Finale Variablen sollen nicht geändert werden, deswegen ist es richtig, dass der Compiler von einem Konstantem Wert ausgeh (das es Möglichkeiten gibt, habe ich geschrieben, diese lassen sich aber afaik durch einen SecurityManager unterbinden)t. Wenn man also streng nach dem Sinn programmiert, ist der Code tatsächlich deadcode.