Sök…


Introduktion

Uttryck i Java är den primära konstruktionen för att göra beräkningar.

Anmärkningar

För operatörer som kan användas i uttryck, se Operatörer .

Operatörens företräde

När ett uttryck innehåller flera operatörer kan det potentiellt läsas på olika sätt. Till exempel kan det matematiska uttrycket 1 + 2 x 3 läsas på två sätt:

  1. Lägg till 1 och 2 och multiplicera resultatet med 3 . Detta ger svaret 9 . Om vi lägger till parenteser så skulle detta se ut ( 1 + 2 ) x 3 .
  2. Lägg till 1 till resultatet av att multiplicera 2 och 3 . Detta ger svaret 7 . Om vi lägger till parenteser så ser det ut som 1 + ( 2 x 3 ) .

I matematik är konventionen att läsa uttrycket på andra sätt. Den allmänna regeln är att multiplikation och delning görs före tillsats och subtraktion. När mer avancerad matematisk notation används är antingen betydelsen "självklart" (till en utbildad matematiker!), Eller parenteser läggs till för att otvetydiga. I båda fallen beror notationens effektivitet för att förmedla mening av matematikernas intelligens och delade kunskap.

Java har samma tydliga regler för hur man läser ett uttryck, baserat på förekomsten av de operatörer som används.

I allmänhet tillskrivs varje operatör ett prioritetsvärde ; se tabellen nedan.

Till exempel:

  1 + 2 * 3

Förekomsten av + är lägre än förekomsten av * , så resultatet av uttrycket är 7, inte 9.

Beskrivning Operatörer / konstruktioner (primär) Företräde associativitet
Qualifier
Parentes
Instans skapande
Fältåtkomst
Array-åtkomst
Metodkallelse
Metodreferens
namn . namn
( expr )
new
primär . namn
primär [ expr ]
primär ( expr, ... )
primär :: namn
15 Vänster till höger
Postökning expr ++ , expr -- 14 -
Försteg
unär
Gjut 1
++ expr, -- expr,
+ Expr, - expr, ~ expr, ! expr,
( typ ) expr
13 -
Höger till vänster
Höger till vänster
multiplikativ * /% 12 Vänster till höger
Tillsats + - 11 Vänster till höger
Flytta << >> >>> 10 Vänster till höger
relations~~POS=TRUNC <> <=> = instanceof 9 Vänster till höger
Jämlikhet ==! = 8 Vänster till höger
Bitvis OCH & 7 Vänster till höger
Bitvis exklusiv ELLER ^ 6 Vänster till höger
Bitvis inklusive ELLER | 5 Vänster till höger
Logiskt OCH && 4 Vänster till höger
Logiskt ELLER || 3 Vänster till höger
Villkorligt 1 ? : 2 Höger till vänster
Uppdrag
Lambda 1
= * = / =% = + = - = << = >> = >>> = & = ^ = | =
->
1 Höger till vänster

1 Lambda-uttrycksprioritet är komplex, eftersom det också kan uppstå efter en roll eller som den tredje delen av den villkorade ternära operatören.

Konstant uttryck

Ett konstant uttryck är ett uttryck som ger en primitiv typ eller en sträng, och vars värde kan utvärderas vid sammanställningstid till en bokstavlig. Uttrycket måste utvärderas utan att göra ett undantag, och det måste endast bestå av följande:

  • Primitiva och strängbokstäver.

  • Skriv utkast till primitiva typer eller String .

  • Följande unary operatörer: + , - , ~ och ! .

  • Följande binära operatörer: * , / , % , + , - , << , >> , >>> , < , <= , > , >= , == != , & , ^ , | , && och || .

  • Den ternära villkorade operatören ? : .

  • Förankrade konstant uttryck.

  • Enkla namn som hänvisar till konstantvariabler. (En konstant variabel är en variabel som deklareras som final där initialiseringsuttrycket i sig är ett konstant uttryck.)

  • Kvalificerade namn på formuläret <TypeName> . <Identifier> som avser konstantvariabler.

Observera att listan ovan exkluderar ++ och -- , tilldelningsoperatörerna, class och instanceof , metodsamtal och referenser till allmänna variabler eller fält.

Konstanta uttryck av typen String resulterar i en "internerad" String , och flytande punktoperationer i konstant uttryck utvärderas med FP-strikt semantik.

Användningar för konstant uttryck

Konstanta uttryck kan användas (nästan) var som helst som ett normalt uttryck kan användas. De har dock en speciell betydelse i följande sammanhang.

Ständiga uttryck krävs för falletiketter i switch-uttalanden. Till exempel:

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

När uttrycket på höger sida av en tilldelning är ett konstant uttryck, kan tilldelningen utföra en primitiv förträngningskonvertering. Detta är tillåtet under förutsättning att värdet på det konstanta uttrycket ligger inom området för typen på vänster sida. (Se JLS 5.1.3 och 5.2 ) Exempel:

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

När ett konstant uttryck används som villkoret i ett do , while eller for , påverkar det läsbarhetsanalysen. Till exempel:

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

(Observera att detta inte gäller if uttalanden. Java-kompilatorn tillåter att then eller else block av ett if uttalande inte kan nås. Detta är Java-analogen för villkorlig kompilering i C och C ++.)

Slutligen initialiseras static final slutfält i en klass eller gränssnitt med konstant uttrycksinitierare ivrigt. Således är det garanterat att dessa konstanter kommer att observeras i initialiserat tillstånd, även när det finns en cykel i klassinitialiseringsberoendegrafen.

Mer information finns i JLS 15.28. Konstant uttryck .

Order för utvärdering av uttryck

Java-uttryck utvärderas enligt följande regler:

  • Operanterna utvärderas från vänster till höger.
  • Operandernas operander utvärderas före operatören.
  • Operatörerna utvärderas enligt operatörens företräde
  • Argumentlistor utvärderas från vänster till höger.

Enkelt exempel

I följande exempel:

int i = method1() + method2();

utvärderingsordningen är:

  1. Den vänstra operanden av = operatör utvärderas till adressen till i .
  2. + Operatörens method1() ) utvärderas.
  3. + Operatörens högra operand ( method2() ) utvärderas.
  4. + -Operationen utvärderas.
  5. = Operation utvärderas, tilldelar resultatet av tillägget till i .

Observera att om samtalens effekter kan observeras kommer du att kunna observera att samtalet till method1 sker före samtalet till method2 .

Exempel med en operatör som har en biverkning

I följande exempel:

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

utvärderingsordningen är:

  1. Den vänstra operanden av = operatör utvärderas. Detta ger adressen till intArray[1] .
  2. Försteget utvärderas. Detta lägger till 1 till i och utvärderas till 2 .
  3. Den högra operand av + utvärderas.
  4. + -Operationen utvärderas till: 2 + 1 -> 3 .
  5. = Operation utvärderas, tilldelar 3 till intArray[1] .

Observera att eftersom den vänstra operanden av = utvärderas först, påverkas den inte av biverkningen av ++i subexpression.

Referens:

Grunderna i uttrycket

Uttryck i Java är den primära konstruktionen för att göra beräkningar. Här är några exempel:

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

I allmänhet består ett uttryck av följande former:

  • Uttrycksnamn som består av:
    • Enkla identifierare; t.ex. någon someIdentifier
    • Kvalificerade identifierare; t.ex. MyClass.someField
  • Primärer som består av:
    • litteraler; t.ex. 1 , 1.0 , 'X' , "hello" , false och null
    • Klass bokstavliga uttryck; t.ex. MyClass.class
    • this och <TypeName> . this
    • Förankrade uttryck; t.ex. ( a + b )
    • Klassinstans skapande uttryck; t.ex. new MyClass(1, 2, 3)
    • Array instanser skapande uttryck; t.ex. new int[3]
    • Fältåtkomstuttryck; t.ex. obj.someField eller this.someField
    • Array åtkomstuttryck; t.ex. vector[21]
    • Metodkallelser; t.ex. obj.doIt(1, 2, 3)
    • Metodreferenser (Java 8 och senare); t.ex. MyClass::doIt
  • Unary operatörsuttryck; t.ex. !a eller i++
  • Binära operatörsuttryck; t.ex. a + b eller obj == null
  • Ternära operatörsuttryck; t.ex. (obj == null) ? 1 : obj.getCount()
  • Lambda-uttryck (Java 8 och senare); t.ex. obj -> obj.getCount()

Detaljerna för de olika formerna av uttryck finns i andra ämnen.

  • Operatörens ämne täcker unära, binära och ternära operatörsuttryck.
  • Ämnet Lambda-uttryck täcker lambda-uttryck och metodreferensuttryck.
  • Ämnet Klasser och objekt täcker uttryck för skapande av klassinstanser.
  • Arrays- ämnet täcker array-åtkomstuttryck och array-inställningsuttryck.
  • Literals ämnet täcker olika typer av litterala uttryck.

Typ av uttryck

I de flesta fall har ett uttryck en statisk typ som kan bestämmas vid sammanställningstidpunkten genom att undersöka och dess suprressioner. Dessa kallas fristående uttryck.

Emellertid (i Java 8 och senare) kan följande slags uttryck vara polyuttryck :

  • Förankrade uttryck
  • Klassinstans skapande uttryck
  • Metodkallelseuttryck
  • Metodreferensuttryck
  • Villkorliga uttryck
  • Lambda-uttryck

När ett uttryck är ett polyuttryck kan dess typ påverkas av uttryckets måttyp ; dvs vad det används för.

Värdet på ett uttryck

Värdet på ett uttryck är tilldelningskompatibelt med dess typ. Undantaget från detta är när högföroreningar har inträffat; t.ex. eftersom varningar om "osäker konvertering" har (felaktigt) undertryckts eller ignorerats.

Uttryck uttalanden

Till skillnad från många andra språk tillåter Java i allmänhet inte uttryck som uttalanden. Till exempel:

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

Eftersom resultatet av att utvärdera ett uttryck som inte kan användas, och eftersom det inte kan påverka genomförandet av programmet på något annat sätt, tog Java-designarna ståndpunkten att en sådan användning antingen är ett misstag eller felaktigt.

Detta gäller dock inte alla uttryck. En delmängd av uttryck är (faktiskt) laglig som uttalanden. Uppsättningen består av:

  • Uppdragsuttryck, inklusive operation-och-blir uppdrag.
  • Uttryck före och efter ökningar och dekrement.
  • Metodsamtal ( void eller ej void ).
  • Klassinstans skapande uttryck.


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow