Suche…


Einführung

Ausdrücke in Java sind das wichtigste Konstrukt für Berechnungen.

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:

  1. Addiere 1 und 2 und multipliziere das Ergebnis mit 3 . Dies gibt die Antwort 9 . Wenn wir Klammern hinzufügen, würde dies wie ( 1 + 2 ) x 3 aussehen.
  2. Addiere 1 zum Ergebnis der Multiplikation von 2 und 3 . Dies gibt die Antwort 7 . Wenn wir Klammern hinzufügen, würde dies wie 1 + ( 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:

  1. Der linke Operand von = Operator wird auf die Adresse von i ausgewertet.
  2. Der linke Operand des + -Operators ( method1() ) wird ausgewertet.
  3. Der rechte Operand des + -Operators ( method2() ) wird ausgewertet.
  4. Die + -Operation wird ausgewertet.
  5. Die = -Operation wird ausgewertet, wobei das Ergebnis der Addition i .

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:

  1. Der linke Operand des Operators = wird ausgewertet. Dies gibt die Adresse von intArray[1] .
  2. Das Vorinkrement wird ausgewertet. Dies addiert 1 zu i und wird zu 2 ausgewertet.
  3. Der rechte Operand des + wird ausgewertet.
  4. Die + -Operation wird ausgewertet als: 2 + 1 -> 3 .
  5. Die = Operation wird ausgewertet, wobei intArray[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
  • Vorwahlen bestehend aus:
    • Literale; zB 1 , 1.0 , 'X' , "hello" , false und null
    • 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 oder this.someField
    • Array-Zugriffsausdrücke; zB vector[21]
    • Methodenaufrufe; zB obj.doIt(1, 2, 3)
    • Methodenreferenzen (Java 8 und höher); zB MyClass::doIt
  • Unäre Operatorausdrücke; zB !a oder i++
  • Binäre Operatorausdrücke; zB a + b oder obj == 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 oder void ).
  • Ausdrücke für die Erstellung von Klasseninstanzen


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow