Java Language
uttryck
Sök…
Introduktion
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:
- Lägg till
1
och2
och multiplicera resultatet med3
. Detta ger svaret9
. Om vi lägger till parenteser så skulle detta se ut( 1 + 2 ) x 3
. - Lägg till
1
till resultatet av att multiplicera2
och3
. Detta ger svaret7
. Om vi lägger till parenteser så ser det ut som1 + ( 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:
- Den vänstra operanden av
=
operatör utvärderas till adressen tilli
. -
+
Operatörensmethod1()
) utvärderas. -
+
Operatörens högra operand (method2()
) utvärderas. -
+
-Operationen utvärderas. -
=
Operation utvärderas, tilldelar resultatet av tillägget tilli
.
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:
- Den vänstra operanden av
=
operatör utvärderas. Detta ger adressen tillintArray[1]
. - Försteget utvärderas. Detta lägger till
1
tilli
och utvärderas till2
. - Den högra operand av
+
utvärderas. -
+
-Operationen utvärderas till:2 + 1
->3
. -
=
Operation utvärderas, tilldelar3
tillintArray[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
- Enkla identifierare; t.ex. någon
- Primärer som består av:
- litteraler; t.ex.
1
,1.0
,'X'
,"hello"
,false
ochnull
- 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
ellerthis.someField
- Array åtkomstuttryck; t.ex.
vector[21]
- Metodkallelser; t.ex.
obj.doIt(1, 2, 3)
- Metodreferenser (Java 8 och senare); t.ex.
MyClass::doIt
- litteraler; t.ex.
- Unary operatörsuttryck; t.ex.
!a
elleri++
- Binära operatörsuttryck; t.ex.
a + b
ellerobj == 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 ejvoid
). - Klassinstans skapande uttryck.