Java Language
Ausdrücke
Suche…
Einführung
Bemerkungen
Eine Referenz zu den Operatoren, die in Ausdrücken verwendet werden können, finden Sie unter Operatoren .
Vorrang des Bedieners
Wenn ein Ausdruck mehrere Operatoren enthält, kann er auf verschiedene Arten gelesen werden. Zum Beispiel kann der mathematische Ausdruck 1 + 2 x 3
auf zwei Arten gelesen werden:
- Addiere
1
und2
und multipliziere das Ergebnis mit3
. Dies gibt die Antwort9
. Wenn wir Klammern hinzufügen, würde dies wie( 1 + 2 ) x 3
aussehen. - Addiere
1
zum Ergebnis der Multiplikation von2
und3
. Dies gibt die Antwort7
. Wenn wir Klammern hinzufügen, würde dies wie1 + ( 2 x 3 )
aussehen.
In der Mathematik lautet die Konvention, den Ausdruck auf die zweite Art zu lesen. Die allgemeine Regel lautet, dass Multiplikation und Division vor Addition und Subtraktion erfolgen. Wenn eine fortgeschrittenere mathematische Notation verwendet wird, ist entweder die Bedeutung entweder "selbstverständlich" (für einen ausgebildeten Mathematiker!) Oder es werden Klammern hinzugefügt, um die Begriffsbestimmung zu erleichtern. In beiden Fällen hängt die Wirksamkeit der Notation zur Vermittlung von Bedeutung von der Intelligenz und dem gemeinsamen Wissen der Mathematiker ab.
Java hat die gleichen klaren Regeln zum Lesen eines Ausdrucks, basierend auf der Priorität der verwendeten Operatoren.
Im Allgemeinen wird jedem Operator ein Vorrangwert zugeordnet . siehe nachstehende Tabelle.
Zum Beispiel:
1 + 2 * 3
Der Vorrang von +
ist niedriger als der Vorrang von *
. Das Ergebnis des Ausdrucks ist also 7 und nicht 9.
Beschreibung | Operatoren / Konstrukte (primär) | Vorrang | Assoziativität |
---|---|---|---|
Qualifikation Klammern Instanzerstellung Feldzugang Array-Zugriff Methodenaufruf Methodenreferenz | Name . Name ( Ausdruck ) new primär . Name primär [ ausdrücken ] primär ( ausdrücken, ... ) primärer :: name | fünfzehn | Links nach rechts |
Post-Inkrement | Ausdruck ++ , Ausdruck -- | 14 | - |
Pre-Inkrement Unary Besetzung 1 | ++ Ausdruck, -- Ausdruck, + Ausdr, - ausdr, ~ ausdr, ! ausdrücken, ( Typ ) Ausdruck | 13 | - Rechts nach links Rechts nach links |
Multiplikativ | * /% | 12 | Links nach rechts |
Zusatzstoff | + - | 11 | Links nach rechts |
Verschiebung | << >> >>> | 10 | Links nach rechts |
Relational | <> <=> = instanceof | 9 | Links nach rechts |
Gleichberechtigung | ==! = | 8 | Links nach rechts |
Bitweises AND | & | 7 | Links nach rechts |
Bitweises exklusives ODER | ^ | 6 | Links nach rechts |
Bitweises ODER | | | 5 | Links nach rechts |
Logisches UND | && | 4 | Links nach rechts |
Logisches ODER | || | 3 | Links nach rechts |
Bedingung 1 | ? : | 2 | Rechts nach links |
Zuordnung Lambda 1 | = * = / =% = + = - = << = >> = >>> = & = ^ = | = -> | 1 | Rechts nach links |
1 Die Priorität von Lambda-Ausdrücken ist komplex, da sie auch nach einem Cast oder als dritter Teil des bedingten ternären Operators auftreten kann.
Konstante Ausdrücke
Ein konstanter Ausdruck ist ein Ausdruck, der einen primitiven Typ oder einen String ergibt und dessen Wert zur Kompilierzeit in ein Literal ausgewertet werden kann. Der Ausdruck muss auswerten, ohne eine Ausnahme auszulösen, und er muss nur aus folgenden Elementen bestehen:
Primitive und String Literale.
Typumwandlungen in primitive Typen oder
String
.Die folgenden unären Operatoren:
+
,-
,~
und!
.Die folgenden binären Operatoren:
*
,/
,%
,+
,-
,<<
,>>
,>>>
,<
,<=
,>
,>=
,==
!=
,&
,^
,|
,&&
und||
.Der ternäre bedingte Operator
?
:
.Konstante Ausdrücke.
Einfache Namen, die sich auf konstante Variablen beziehen. (Eine konstante Variable ist eine als
final
deklarierte Variable, bei der der Initialisierungsausdruck selbst ein konstanter Ausdruck ist.)Qualifizierte Namen der Form
<TypeName> . <Identifier>
, die sich auf konstante Variablen beziehen.
Beachten Sie, dass die oben aufgeführte Liste umfasst nicht ++
und --
die Zuweisungsoperatoren, class
und instanceof
, Methodenaufrufe und Verweise auf allgemeine Variablen oder Felder.
Konstante Ausdrücke vom Typ String
führen zu einer "internierten" String
, und Fließkommaoperationen in konstanten Ausdrücken werden mit FP-strikter Semantik ausgewertet.
Verwendet für konstante Ausdrücke
Konstante Ausdrücke können (fast) überall dort verwendet werden, wo ein normaler Ausdruck verwendet werden kann. Sie haben jedoch in den folgenden Zusammenhängen eine besondere Bedeutung.
Konstante Ausdrücke sind für die Bezeichnung von Beschriftungen in switch-Anweisungen erforderlich. Zum Beispiel:
switch (someValue) {
case 1 + 1: // OK
case Math.min(2, 3): // Error - not a constant expression
doSomething();
}
Wenn der Ausdruck auf der rechten Seite einer Zuweisung ein konstanter Ausdruck ist, kann die Zuweisung eine primitive Verengungsumwandlung durchführen. Dies ist zulässig, vorausgesetzt, der Wert des konstanten Ausdrucks liegt innerhalb des Bereichs des Typs auf der linken Seite. (Siehe JLS 5.1.3 und 5.2 ) Zum Beispiel:
byte b1 = 1 + 1; // OK - primitive narrowing conversion.
byte b2 = 127 + 1; // Error - out of range
byte b3 = b1 + 1; // Error - not a constant expession
byte b4 = (byte) (b1 + 1); // OK
Wenn ein konstanter Ausdruck als Bedingung in einer verwendet wird , do
, while
oder for
, dann betrifft es die Lesbarkeit Analyse. Zum Beispiel:
while (false) {
doSomething(); // Error - statenent not reachable
}
boolean flag = false;
while (flag) {
doSomething(); // OK
}
(Beachten Sie, dass dies nicht gilt, if
Anweisungen verwendet werden. Der Java-Compiler lässt zu, dass der then
oder else
Block einer if
-Anweisung nicht erreichbar ist. Dies ist das Java-Analog der bedingten Kompilierung in C und C ++.)
Schließlich werden static final
Felder in einer Klasse oder Schnittstelle mit konstanten Ausdrucksinitialisierern eifrig initialisiert. Somit ist garantiert, dass diese Konstanten im initialisierten Zustand beobachtet werden, selbst wenn ein Zyklus im Abhängigkeitsgraphen der Klasseninitialisierung vorliegt.
Weitere Informationen finden Sie in JLS 15.28. Konstante Ausdrücke .
Reihenfolge der Ausdrucksauswertung
Java-Ausdrücke werden nach folgenden Regeln ausgewertet:
- Operanden werden von links nach rechts ausgewertet.
- Die Operanden eines Operators werden vor dem Operator ausgewertet.
- Operatoren werden nach der Priorität des Operators bewertet
- Argumentlisten werden von links nach rechts ausgewertet.
Einfaches Beispiel
Im folgenden Beispiel:
int i = method1() + method2();
Die Reihenfolge der Bewertung lautet:
- Der linke Operand von
=
Operator wird auf die Adresse voni
ausgewertet. - Der linke Operand des
+
-Operators (method1()
) wird ausgewertet. - Der rechte Operand des
+
-Operators (method2()
) wird ausgewertet. - Die
+
-Operation wird ausgewertet. - Die
=
-Operation wird ausgewertet, wobei das Ergebnis der Additioni
.
Wenn die Auswirkungen der Aufrufe beobachtbar sind, können Sie feststellen, dass der Aufruf von method1
vor dem Aufruf von method2
.
Beispiel mit einem Operator, der eine Nebenwirkung hat
Im folgenden Beispiel:
int i = 1;
intArray[i] = ++i + 1;
Die Reihenfolge der Bewertung lautet:
- Der linke Operand des Operators
=
wird ausgewertet. Dies gibt die Adresse vonintArray[1]
. - Das Vorinkrement wird ausgewertet. Dies addiert
1
zui
und wird zu2
ausgewertet. - Der rechte Operand des
+
wird ausgewertet. - Die
+
-Operation wird ausgewertet als:2 + 1
->3
. - Die
=
Operation wird ausgewertet, wobeiintArray[1]
3
intArray[1]
.
Beachten Sie, dass der linke Operand von =
zuerst ausgewertet wird und nicht durch die Nebenwirkung des ++i
Unterausdrucks beeinflusst wird.
Referenz:
Grundlagen des Ausdrucks
Ausdrücke in Java sind das wichtigste Konstrukt für Berechnungen. Hier sind einige Beispiele:
1 // A simple literal is an expression
1 + 2 // A simple expression that adds two numbers
(i + j) / k // An expression with multiple operations
(flag) ? c : d // An expression using the "conditional" operator
(String) s // A type-cast is an expression
obj.test() // A method call is an expression
new Object() // Creation of an object is an expression
new int[] // Creation of an object is an expression
Ein Ausdruck besteht im Allgemeinen aus den folgenden Formen:
- Ausdrucksnamen, bestehend aus:
- Einfache Bezeichner; zB
someIdentifier
- Qualifizierte Identifikatoren; zB
MyClass.someField
- Einfache Bezeichner; zB
- Vorwahlen bestehend aus:
- Literale; zB
1
,1.0
,'X'
,"hello"
,false
undnull
- Wörtliche Ausdrücke der Klasse; zB
MyClass.class
-
this
und<TypeName> . this
- Eingeklammerte Ausdrücke; zB
( a + b )
- Ausdrücke zur Erstellung von Klasseninstanzen; zB
new MyClass(1, 2, 3)
- Ausdrücke zur Erstellung von Array-Instanzen; zB
new int[3]
- Feldzugriffsausdrücke; zB
obj.someField
oderthis.someField
- Array-Zugriffsausdrücke; zB
vector[21]
- Methodenaufrufe; zB
obj.doIt(1, 2, 3)
- Methodenreferenzen (Java 8 und höher); zB
MyClass::doIt
- Literale; zB
- Unäre Operatorausdrücke; zB
!a
oderi++
- Binäre Operatorausdrücke; zB
a + b
oderobj == null
- Ternäre Operatorausdrücke; zB
(obj == null) ? 1 : obj.getCount()
- Lambda-Ausdrücke (Java 8 und höher); zB
obj -> obj.getCount()
Die Details zu den verschiedenen Ausdrucksformen finden Sie in anderen Themen.
- Das Thema Operatoren behandelt unäre, binäre und ternäre Operatorausdrücke.
- Das Thema Lambda-Ausdrücke deckt Lambda-Ausdrücke und Methodenreferenzausdrücke ab.
- Das Thema Klassen und Objekte behandelt Ausdrücke zur Erstellung von Klasseninstanzen.
- Das Thema Arrays behandelt Array-Zugriffsausdrücke und Array-Instanzerstellungsausdrücke.
- Das Thema Literale behandelt die verschiedenen Arten von literalen Ausdrücken.
Der Typ eines Ausdrucks
In den meisten Fällen hat ein Ausdruck einen statischen Typ, der zur Kompilierzeit durch Untersuchen und dessen Unterausdrücke bestimmt werden kann. Diese werden als eigenständige Ausdrücke bezeichnet.
Die folgenden Arten von Ausdrücken können jedoch (in Java 8 und höher) Polyausdrücke sein :
- Eingeklammerte Ausdrücke
- Ausdrücke für die Erstellung von Klasseninstanzen
- Methodenaufrufausdrücke
- Methodenreferenzausdrücke
- Bedingte Ausdrücke
- Lambda-Ausdrücke
Wenn ein Ausdruck ein Poly Ausdruck ist, kann seine Aktivität durch den Zieltyp des Ausdrucks beeinflußt werden; dh wofür es verwendet wird.
Der Wert eines Ausdrucks
Der Wert eines Ausdrucks ist mit seinem Typ kompatibel. Die Ausnahme ist, wenn eine Haufenverschmutzung aufgetreten ist; z. B. weil "unsichere Konvertierungswarnungen" (unangemessen) unterdrückt oder ignoriert wurden.
Ausdrucksanweisungen
Im Gegensatz zu vielen anderen Sprachen erlaubt Java im Allgemeinen nicht, Ausdrücke als Anweisungen zu verwenden. Zum Beispiel:
public void compute(int i, int j) {
i + j; // ERROR
}
Da das Ergebnis der Auswertung eines Ausdrucks like nicht verwendet werden kann und die Ausführung des Programms auf keine andere Weise beeinflusst werden kann, haben die Java-Designer die Auffassung vertreten, dass eine solche Verwendung entweder ein Fehler ist oder falsch ist.
Dies gilt jedoch nicht für alle Ausdrücke. Eine Teilmenge von Ausdrücken ist als Aussagen rechtlich zulässig. Das Set umfasst:
- Zuweisungsausdruck, einschließlich Zuweisungen von Vorgängen .
- Inkrement- und Dekrement-Ausdrücke vor und nach dem Schreiben.
- Methodenaufrufe (
void
odervoid
). - Ausdrücke für die Erstellung von Klasseninstanzen