Szukaj…


Wprowadzenie

Wyrażenia w Javie są podstawową konstrukcją do wykonywania obliczeń.

Uwagi

Aby uzyskać informacje na temat operatorów, które mogą być używane w wyrażeniach, zobacz Operatory .

Priorytet operatora

Gdy wyrażenie zawiera wiele operatorów, można je odczytać na różne sposoby. Na przykład wyrażenie matematyczne 1 + 2 x 3 można odczytać na dwa sposoby:

  1. Dodaj 1 i 2 i pomnóż wynik przez 3 . To daje odpowiedź 9 . Gdybyśmy dodali nawiasy, wyglądałoby to na ( 1 + 2 ) x 3 .
  2. Dodaj 1 do wyniku pomnożenia 2 i 3 . To daje odpowiedź 7 . Gdybyśmy dodali nawiasy, wyglądałoby to na 1 + ( 2 x 3 ) .

W matematyce konwencja polega na odczytywaniu wyrażenia w drugą stronę. Ogólna zasada jest taka, że mnożenie i dzielenie odbywa się przed dodawaniem i odejmowaniem. Gdy używana jest bardziej zaawansowana notacja matematyczna, albo albo „oczywiste” (dla wyszkolonego matematyka!), Albo nawiasy są dodawane w celu jednoznaczności. W obu przypadkach skuteczność notacji w przekazywaniu znaczenia zależy od inteligencji i wspólnej wiedzy matematyków.

Java ma takie same jasne zasady dotyczące odczytywania wyrażeń, w oparciu o pierwszeństwo używanych operatorów.

Zasadniczo każdemu operatorowi przypisuje się wartość pierwszeństwa ; patrz tabela poniżej.

Na przykład:

  1 + 2 * 3

Priorytet + jest niższy niż priorytet * , więc wynikiem wyrażenia jest 7, a nie 9.

Opis Operatory / konstrukcje (podstawowe) Precedens Stowarzyszenie
Kwalifikator
Zdanie wtrącone
Tworzenie instancji
Dostęp do pola
Dostęp do tablicy
Wywołanie metody
Odniesienie do metody
wymienić . Nazwa
( expr )
new
podstawowy . Nazwa
podstawowy [ wyrażenie ]
podstawowy ( expr, ... )
podstawowe :: nazwa
15 Z lewej na prawą
Przyrost postu expr ++ , expr -- 14 -
Wstępny przyrost
Unary
Obsada 1
++ expr, -- expr,
+ Expr, - wyrażenie, ~ expr, ! expr,
( typ ) expr
13 -
Od prawej do lewej
Od prawej do lewej
Mnożny * /% 12 Z lewej na prawą
Przyłączeniowy + - 11 Z lewej na prawą
Zmiana << >> >>> 10 Z lewej na prawą
Relacyjny <> <=> = instanceof 9 Z lewej na prawą
Równość ==! = 8 Z lewej na prawą
Bitowe AND I 7 Z lewej na prawą
Wyłącznie bitowe OR ^ 6 Z lewej na prawą
Bitowe włącznie OR | 5 Z lewej na prawą
Logiczne AND I & 4 Z lewej na prawą
Logiczne OR || 3) Z lewej na prawą
Warunkowe 1 ? : 2) Od prawej do lewej
Zadanie
Lambda 1
= * = / =% = + = - = << = >> = >>> = & = ^ = | =
->
1 Od prawej do lewej

1 Pierwszeństwo wyrażeń lambda jest złożone, ponieważ może wystąpić także po rzutowaniu lub jako trzecia część warunkowego operatora trójskładnikowego.

Wyrażenia stałe

Stałe wyrażenie jest wyrażeniem, które zwraca typ pierwotny lub ciąg znaków, i którego wartość można oszacować w czasie kompilacji do literału. Wyrażenie musi oceniać bez zgłaszania wyjątku i musi się składać tylko z następujących elementów:

  • Literały pierwotne i łańcuchowe.

  • Rzutowanie typów na typy pierwotne lub String .

  • Następujące jednoargumentowe operatory: + , - , ~ i ! .

  • Następujące operatory binarne: * , / , % , + , - , << , >> , >>> , < , <= , > , >= , == != , & , ^ , | , && i || .

  • Trójskładnikowy operator warunkowy ? : .

  • Stałe wyrażenia w nawiasach.

  • Proste nazwy odnoszące się do zmiennych stałych. (Zmienna stała jest zmienną zadeklarowaną jako final gdzie samo wyrażenie inicjujące jest wyrażeniem stałym).

  • Nazwy kwalifikowane w postaci <TypeName> . <Identifier> które odnoszą się do zmiennych stałych.

Zauważ, że powyższa lista wyklucza ++ i -- , operatory przypisania, class i instanceof , wywołania metod i odwołania do zmiennych ogólnych lub pól.

Stałe wyrażenia typu String skutkują „wewnętrznym” String , a operacje zmiennoprzecinkowe w wyrażeniach stałych są oceniane za pomocą semantyki ścisłej dla FP.

Używa wyrażeń stałych

Wyrażeń stałych można używać (prawie) wszędzie tam, gdzie można zastosować wyrażenie normalne. Mają jednak szczególne znaczenie w następujących kontekstach.

Wyrażenia stałe są wymagane dla etykiet przypadków w instrukcjach przełączników. Na przykład:

switch (someValue) {
case 1 + 1:            // OK
case Math.min(2, 3):   // Error - not a constant expression
    doSomething();
}

Jeśli wyrażenie po prawej stronie przypisania jest wyrażeniem stałym, wówczas przypisanie może wykonać prymitywną konwersję zwężającą. Jest to dozwolone pod warunkiem, że wartość stałego wyrażenia mieści się w zakresie typu po lewej stronie. (Patrz JLS 5.1.3 i 5.2 ) Na przykład:

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

Kiedy wyrażenie stałe jest używane jako warunek w do , while lub for , wówczas wpływa na analizę czytelności. Na przykład:

while (false) {
    doSomething();           // Error - statenent not reachable
}
boolean flag = false;
while (flag) {
    doSomething();           // OK
}

(Uwaga: nie dotyczy if instrukcji if . Kompilator Java pozwala na niedostępność bloku instrukcji if then lub w else if . Jest to analog Java w kompilacji warunkowej w C i C ++.)

Wreszcie static final pola static final w klasie lub interfejsie ze stałymi inicjalizatorami wyrażeń są inicjowane z niecierpliwością. W ten sposób gwarantuje się, że stałe te będą przestrzegane w stanie inicjalizacji, nawet jeśli na wykresie zależności inicjalizacji klasy występuje cykl.

Aby uzyskać więcej informacji, zobacz JLS 15.28. Wyrażenia stałe .

Kolejność oceny wyrażeń

Wyrażenia Java są oceniane według następujących reguł:

  • Operandy są oceniane od lewej do prawej.
  • Operandy operatora są oceniane przed operatorem.
  • Operatory są oceniane według priorytetu operatorów
  • Listy argumentów są oceniane od lewej do prawej.

Prosty przykład

W poniższym przykładzie:

int i = method1() + method2();

kolejność oceny jest następująca:

  1. Lewy operand operatora = jest przetwarzany na adres i .
  2. Oceniany jest lewy operand operatora + ( method1() ).
  3. method2() jest prawy argument operatora + ( method2() ).
  4. Operacja + jest oceniana.
  5. Operacja = jest oceniana, przypisując wynik dodania do i .

Zauważ, że jeśli efekty wywołań są obserwowalne, będziesz w stanie zauważyć, że wywołanie metody method1 występuje przed wywołaniem method2 .

Przykład z operatorem, który ma efekt uboczny

W poniższym przykładzie:

int i = 1;
intArray[i] = ++i + 1;

kolejność oceny jest następująca:

  1. Oceniany jest lewy operand operatora = . Daje to adres intArray[1] .
  2. Wstępny przyrost jest oceniany. Dodaje to 1 do i , a ocenia na 2 .
  3. Operand prawej + jest oceniany.
  4. Operacja + jest oceniana na: 2 + 1 -> 3 .
  5. Operacja = jest oceniana, przypisując 3 do intArray[1] .

Zauważ, że ponieważ lewostronny argument = jest oceniany jako pierwszy, nie ma na niego wpływu efekt uboczny podwyrażenia ++i .

Odniesienie:

Podstawy wyrażeń

Wyrażenia w Javie są podstawową konstrukcją do wykonywania obliczeń. Oto kilka przykładów:

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

Ogólnie wyrażenie składa się z następujących form:

  • Nazwy wyrażeń, które składają się z:
    • Proste identyfikatory; np. someIdentifier
    • Kwalifikowane identyfikatory; np. MyClass.someField
  • Podstawowe, które składają się z:
    • Literały; np. 1 , 1.0 , 'X' , "hello" , false i null
    • Klasowe wyrażenia dosłowne; np. MyClass.class
    • this i <TypeName> . this
    • Wyrażenia w nawiasach; np. ( a + b )
    • Wyrażenia związane z tworzeniem instancji klasy; np. new MyClass(1, 2, 3)
    • Wyrażenia tworzenia instancji Array; np. new int[3]
    • Wyrażenia dostępu do pola; np. obj.someField lub this.someField
    • Wyrażenia dostępu do tablicy; np. vector[21]
    • Wywoływanie metod; np. obj.doIt(1, 2, 3)
    • Odwołania do metod (Java 8 i nowsze); np. MyClass::doIt
  • Jednoznaczne wyrażenia operatora; np !a lub i++
  • Wyrażenia operatora binarnego; np. a + b lub obj == null
  • Wyrażenia operatora trójskładnikowego; np. (obj == null) ? 1 : obj.getCount()
  • Wyrażenia lambda (Java 8 i nowsze); np. obj -> obj.getCount()

Szczegóły dotyczące różnych form wyrażeń można znaleźć w innych tematach.

  • Temat Operatory obejmuje wyrażenia jednoargumentowe, binarne i trójskładnikowe.
  • Temat Wyrażenia lambda obejmuje wyrażenia lambda i wyrażenia referencyjne metod.
  • Temat Klasy i obiekty obejmuje wyrażenia tworzenia instancji klasy.
  • Temat Tablice obejmuje wyrażenia dostępu do tablicy i wyrażenia tworzenia instancji tablicy.
  • Temat Literały obejmuje różne rodzaje wyrażeń dosłownych.

Rodzaj wyrażenia

W większości przypadków wyrażenie ma typ statyczny, który można określić w czasie kompilacji poprzez badanie i jego podwyrażenia. Są to tak zwane wyrażenia autonomiczne .

Jednak (w Javie 8 i nowszych) następujące wyrażenia mogą być wyrażeniami wielowymiarowymi :

  • Wyrażenia w nawiasach
  • Wyrażenia tworzenia instancji klasy
  • Wyrażenia wywołania metody
  • Wyrażenia odniesienia do metody
  • Wyrażenia warunkowe
  • Wyrażenia lambda

Gdy wyrażenie jest wyrażeniem poli, na jego typ może wpływać typ docelowy wyrażenia; tj. do czego jest używany.

Wartość wyrażenia

Wartość wyrażenia jest przypisaniem zgodnym z jego typem. Wyjątkiem jest sytuacja, gdy wystąpiło zanieczyszczenie hałdy ; np. ponieważ ostrzeżenia o „niebezpiecznej konwersji” zostały (niewłaściwie) stłumione lub zignorowane.

Instrukcje wyrażeń

W przeciwieństwie do wielu innych języków, Java ogólnie nie pozwala na używanie wyrażeń jako instrukcji. Na przykład:

public void compute(int i, int j) {
    i + j;   // ERROR
}

Ponieważ wynik oceny wyrażenia typu „nie można użyć”, a ponieważ nie może on wpłynąć na wykonanie programu w żaden inny sposób, projektanci Java stwierdzili, że takie użycie jest błędne lub mylące.

Nie dotyczy to jednak wszystkich wyrażeń. Podzbiór wyrażeń jest (w rzeczywistości) legalny jako oświadczenie. Zestaw zawiera:

  • Wyrażenie przypisania, w tym operacje i staje się przypisaniami.
  • Wyrażenia zwiększające i zmniejszające przed i po.
  • Wywołania metod ( void lub non- void ).
  • Wyrażenia tworzenia instancji klasy.


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow