java 8: Unterschied zwischen class.getName () und String literal [duplicate]

7

Ich habe am Switch-Fall gearbeitet.

Wenn wir class.getName () verwenden, dann bekomme ich den Fehler, dass "case-Ausdrücke konstante Ausdrücke sein müssen" wie folgt:

%Vor%

Auch wenn wir folgendes tun, nehmen wir den Namen der String-Klasse in eine Konstante, und erhalten dann denselben Fehler:

%Vor%

Aber wenn ich folgendes tue, benutze das String-Literal "java.lang.String", es gibt keinen Fehler:

%Vor%

Kann jemand bitte das erklären, warum es nicht die ersten zwei Fälle nimmt und den letzten nimmt? Vielen Dank im Voraus.

    
Krishna Kumar 11.11.2015, 08:11
quelle

3 Antworten

8

classObject.getName() ist ein Methodenaufruf, und die Ergebnisse von Methodenaufrufen sind definitionsgemäß keine Kompilierzeitkonstanten. Ein String-Literal ist eine Kompilierzeitkonstante.

Beachten Sie, dass viele Situationen zwar einen static final -Referenzwert als Konstante für die Lebensdauer des Programms benötigen, ein switch jedoch seine Optionen zur Kompilierungszeit fest codieren muss. Der Wert eines case -Ziels muss entweder ein Enum-Wert oder eine (Kompilierungszeit) ConstantExpression .

    
chrylis 11.11.2015, 08:14
quelle
6

Jedes Case-Label muss ein "konstanter Ausdruck" sein. Was "konstanter Ausdruck" ist, ist in Java Language Standard definiert, § 15.28 Konstante Ausdrücke :

  

Ein kompilierbarer Konstantenausdruck ist ein Ausdruck, der einen Wert des primitiven Typs oder eines Strings angibt, der nicht abrupt beendet wird und nur mit folgendem Aufbau verwendet wird:

     
  • Literale des primitiven Typs und Literale des Typs String
  •   

...

     
  • Einfache Namen, die sich auf konstante Variablen beziehen
  •   

Dort sind keine Methodenaufrufe aufgelistet, daher kann das Methodenaufrufergebnis nicht der Konstantenausdruck sein, auch wenn die Methode trivial ist. Aber "Einfache Namen, die sich auf konstante Variablen beziehen" sind hier aufgelistet, daher ist die Referenz auf die konstante Variable auch eine Konstante.

    
Tagir Valeev 11.11.2015 08:18
quelle
4
___ qstnhdr ___ java 8: Unterschied zwischen class.getName () und String literal [duplicate] ___ qstntxt ___

Ich habe am Switch-Fall gearbeitet.

Wenn wir class.getName () verwenden, dann bekomme ich den Fehler, dass "case-Ausdrücke konstante Ausdrücke sein müssen" wie folgt:

%Vor%

Auch wenn wir folgendes tun, nehmen wir den Namen der String-Klasse in eine Konstante, und erhalten dann denselben Fehler:

%Vor%

Aber wenn ich folgendes tue, benutze das String-Literal "java.lang.String", es gibt keinen Fehler:

%Vor%

Kann jemand bitte das erklären, warum es nicht die ersten zwei Fälle nimmt und den letzten nimmt? Vielen Dank im Voraus.

    
___ tag123switchstatement ___ In der Computerprogrammierung ist eine switch-, case-, select- oder inspect-Anweisung eine Art von Auswahlkontrollmechanismus ___ answer33646572 ___

Jedes Case-Label muss ein "konstanter Ausdruck" sein. Was "konstanter Ausdruck" ist, ist in Java Language Standard definiert, § 15.28 Konstante Ausdrücke :

  

Ein kompilierbarer Konstantenausdruck ist ein Ausdruck, der einen Wert des primitiven Typs oder eines Strings angibt, der nicht abrupt beendet wird und nur mit folgendem Aufbau verwendet wird:

     
  • Literale des primitiven Typs und Literale des Typs String
  •   

...

     
  • Einfache Namen, die sich auf konstante Variablen beziehen
  •   

Dort sind keine Methodenaufrufe aufgelistet, daher kann das Methodenaufrufergebnis nicht der Konstantenausdruck sein, auch wenn die Methode trivial ist. Aber "Einfache Namen, die sich auf konstante Variablen beziehen" sind hier aufgelistet, daher ist die Referenz auf die konstante Variable auch eine Konstante.

    
___ answer3366618 ___

Der Grund, warum dies nicht funktioniert, ist, dass der Wert des einzuschaltenden case bei der Kompilierung bekannt sein muss (weil er im Bytecode fest codiert und inline ist).

String.class.getName() ist ein Methodenaufruf, der zur Laufzeit ausgewertet wird . Ja, static final garantiert, dass es sich nach dem ersten Laden der Klasse nicht ändert. Aber das alles ist lange nach der Kompilierzeit.

Der Compiler ruft keinen Code aus dem Quellcode der Anwendung auf (möglicherweise mit Ausnahme der Annotationsverarbeitung). Es kompiliert es nur.

    
___ tag123constants ___ Konstanten in der Programmierung sind Definitionen, deren Wert während der Ausführung eines Programms festgelegt ist. Literale in den meisten Sprachen sind zum Beispiel Konstanten. In referenziell transparenten Programmierstilen sind alle Definitionen konstant. ___ tag123java8 ___ Verwenden Sie dieses Tag für spezifische Fragen zu Java 8, Version 8 (interne Nummer 1.8) der Java-Plattform, die am 18. März 2014 veröffentlicht wurde. In den meisten Fällen sollten Sie auch das Java-Tag angeben. ___ tag123java ___ Java (nicht zu verwechseln mit JavaScript oder JScript oder JS) ist eine universelle objektorientierte Programmiersprache, die für die Verwendung in Verbindung mit der Java Virtual Machine (JVM) entwickelt wurde. "Java-Plattform" ist der Name für ein Computersystem, auf dem Tools zum Entwickeln und Ausführen von Java-Programmen installiert sind. Verwenden Sie dieses Tag für Fragen, die sich auf die Java-Programmiersprache oder Java-Plattform-Tools beziehen. ___ tag123stringliterals ___ Stringliterale betreffen die syntaktische Darstellung von Literalkonstantenstrings in C und C ++. ___ answer33646528 ___

%code% ist ein Methodenaufruf, und die Ergebnisse von Methodenaufrufen sind definitionsgemäß keine Kompilierzeitkonstanten. Ein String-Literal ist eine Kompilierzeitkonstante.

Beachten Sie, dass viele Situationen zwar einen %code% -Referenzwert als Konstante für die Lebensdauer des Programms benötigen, ein %code% jedoch seine Optionen zur Kompilierungszeit fest codieren muss. Der Wert eines %code% -Ziels muss entweder ein Enum-Wert oder eine (Kompilierungszeit) %code% .

    
___
Thilo 11.11.2015 08:22
quelle