サーチ…


前書き

Javaの式は、計算を行うための主要な構成要素です。

備考

式で使用できる演算子の参照については、 演算子を

オペレータの優先順位

ある式に複数の演算子が含まれている場合、異なる方法で読み取る可能性があります。例えば、数式1 + 2 x 3は2つの方法で読み取ることができます。

  1. 12を加え、結果に3を掛けます。これは答えを与える9 。かっこを追加すると、 ( 1 + 2 ) x 3ます。
  2. 23を乗算した結果に1を加えます。これは答えを与える7 。かっこを追加すると、 1 + ( 2 x 3 )ます。

数学では、式は2番目の方法で読むことがコンベンションです。一般的な規則は、乗算と除算が加算と減算の前に行われることです。より進んだ数学的表記法が使用されるとき、意味は「自明」(訓練された数学者にとって!)か、または曖昧さを除去するために括弧が追加されます。どちらの場合でも、意味を伝える表記の有効性は、数学者の知性と知識に依存します。

Javaには、使用されている演算子の優先順位に基づいて、式を読み取る方法に関する同じ明確な規則があります。

一般に、各演算子は優先順位値に帰される。下記の表を参照してください。

例えば:

  1 + 2 * 3

+の優先順位は*の優先順位よりも低いため、式の結果は9ではなく7です。

説明演算子/構造体(プライマリ) 優先順位関連性
修飾子
括弧
インスタンスの作成
フィールドアクセス
配列アクセス
メソッド呼び出し
メソッド参照
名前.
( expr )
new
主要.
プライマリ[ expr ]
プライマリ( expr、... )
primary :: name
15 左から右へ
ポストインクリメント expr ++ 、expr -- 14 -
プリインクリメント
単項
キャスト1
++ expr、 -- expr、
+ exprは、 -式expr、 ~式expr、 ! expr、
() expr
13 -
右から左へ
右から左へ
乗法 * /% 12 左から右へ
添加剤 + - 11 左から右へ
シフト << >> >>> 10 左から右へ
リレーショナル <> <=> = instanceof 9 左から右へ
平等 ==!= 8 左から右へ
ビット単位AND そして、 7 左から右へ
ビットごとの排他的論理和 ^ 6 左から右へ
ビット単位OR | 5 左から右へ
論理AND && 4 左から右へ
論理OR || 3 左から右へ
条件1 ? : 2 右から左へ
割り当て
ラムダ1
= = = = = = = = = = = << = >> = >>> =&= ^ = = =
- >
1 右から左へ

1ラムダ式の優先順位は、キャスト後、または条件付き3項演算子の3番目の部分としても発生するため、複雑です。

定数式

定数式は、プリミティブ型またはStringを生成する式であり、その値はコンパイル時にリテラルに評価されます。式は例外をスローせずに評価する必要があり、次のものだけで構成されている必要があります。

  • プリミティブと文字列リテラル。

  • 型はプリミティブ型またはStringキャストされます。

  • 以下の単項演算子: +-~ !

  • */%+-<< >>>>><<=>>===!=&^|&&||

  • 三項条件演算子? :

  • 括弧内の定数式。

  • 定数変数を参照する単純な名前。 (定数は、 finalと宣言された変数で、初期化子の式自体は定数式です。)

  • <TypeName> . <Identifier>の形式の修飾名<TypeName> . <Identifier>は定数変数を参照します。

上記のリストには、 ++-- 、代入演算子、 classinstanceof 、メソッド呼び出し、および一般的な変数やフィールドの参照は除外されています。

String型の定数式は "interned" Stringになり、定数式の浮動小数点演算はFP厳密セマンティクスで評価されます。

定数式の使用

定数式は、通常の式を使用できる場所であればどこでも使用できます。しかしながら、それらは以下の文脈において特別な意味を有する。

switch文のcaseラベルには定数式が必要です。例えば:

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

代入の右辺の式が定数式である場合、代入はプリミティブなナロー変換を実行できます。これは、定数式の値が左側の型の範囲内であれば許されます。 ( JLS 5.1.35.2を参照)例:

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

dowhileまたはfor条件として定数式を使用すると、可読性分析に影響します。例えば:

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

(これは適用されないことに注意してくださいif 、Javaコンパイラができますステートメント。 thenまたはelseのブロックif到達不能であることを声明を。これは、CおよびC ++での条件付きコンパイルのJavaのアナログです。)

最後に、定数式イニシャライザを持つクラスまたはインターフェイス内のstatic finalフィールドが賢く初期化されます。したがって、クラス初期化依存グラフにサイクルがあっても、初期化された状態でこれらの定数が観測されることが保証されます。

詳細は、 JLS 15.28を参照してください。定数式

式の評価順序

Java式は次の規則に従って評価されます。

  • オペランドは左から右に評価されます。
  • オペレータのオペランドは、オペレータの前で評価されます。
  • 演算子は、演算子の優先順位に従って評価されます。
  • 引数リストは左から右に評価されます。

簡単な例

次の例では、

int i = method1() + method2();

評価の順序は次のとおりです。

  1. =演算子の左オペランドは、 iのアドレスに評価されます。
  2. +演算子の左側のオペランド( method1() )が評価されます。
  3. +演算子( method2() )の右オペランドが評価されます。
  4. +演算が評価されます。
  5. =演算が評価され、加算の結果がiに代入されます。

呼び出しの影響が観測可能な場合、 method1の呼び出しはmethod2の呼び出しの前に発生することがmethod2ます。

副作用を持つ演算子を使用した例

次の例では、

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

評価の順序は次のとおりです。

  1. =演算子の左オペランドが評価されます。これにより、 intArray[1]アドレスが得られます。
  2. プリインクリメントが評価されます。これはi1を加え、 2と評価します。
  3. +の右側のオペランドが評価されます。
  4. +演算は、 2 + 1 - > 3と評価されます。
  5. =演算が評価され、 intArray[1] 3が代入されます。

左オペランドのでことに注意=最初に評価され、それはの副作用の影響を受けない++i部分式。

参照:

表現の基礎

Javaの式は、計算を行うための主要な構成要素です。ここではいくつかの例を示します。

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

一般に、式は次の形式で構成されます。

  • 式の名前は次のもので構成されます。
    • 単純な識別子。例: someIdentifier
    • 修飾された識別子。例: MyClass.someField
  • 次からなる原資:
    • リテラル;例えば11.0'X' "hello"falsenull
    • クラスのリテラル式。例: MyClass.class
    • this<TypeName> . this
    • 括弧内の式。例えば( a + b )
    • クラスインスタンス作成式。 new MyClass(1, 2, 3)
    • 配列インスタンス作成式。 new int[3]
    • フィールドアクセス式。例: obj.someFieldまたはthis.someField
    • 配列アクセス式。例えばvector[21]
    • メソッド呼び出し。例えば、 obj.doIt(1, 2, 3)
    • メソッド参照(Java 8以降)。例: MyClass::doIt
  • 単項演算子式。例えば!aまたはi++
  • バイナリ演算子式。例えばa + bまたはobj == null
  • 三項演算子の式。例えば(obj == null) ? 1 : obj.getCount()
  • ラムダ式(Java 8以降)。例: obj -> obj.getCount()

さまざまな表現形式の詳細は、他のトピックにあります。

  • 演算子のトピックでは、単項演算子 、二項演算子、三項演算子の式について説明します。
  • ラムダ式のトピックでは、ラムダ式とメソッド参照式について説明します。
  • クラスとオブジェクトのトピックでは、クラスインスタンスの作成式について説明します。
  • 配列トピックでは、配列アクセス式と配列インスタンス作成式について説明します。
  • リテラルトピックでは、リテラル表現のさまざまな種類について説明します。

表現のタイプ

ほとんどの場合、式は、コンパイル時に検査してその部分式を決定することができる静的型を持ちます。これらは、 独立型式と呼ばれます。

しかし、(Java 8以降では)次の種類の式はポリ式である可能性があります。

  • 括弧内の式
  • クラスインスタンス作成式
  • メソッド呼び出し式
  • メソッド参照式
  • 条件式
  • ラムダ式

式がポリ式である場合、その型は式のターゲット型の影響を受ける可能性があります。それが何のために使われているのか。

式の値

式の値はその型と割り当て互換です。例外はヒープ汚染が発生した場合です。たとえば、「安全でない変換」の警告が(不適切に)抑制されたり無視されたりしているためです。

式ステートメント

他の多くの言語とは異なり、Javaでは一般的に式を文として使用することはできません。例えば:

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

このような表現を評価した結果は使用できないため、他の方法でプログラムの実行に影響を及ぼすことができないため、Javaの設計者はそのような使用法が間違いか誤っているという立場を取った。

ただし、これはすべての式に当てはまるわけではありません。式のサブセットは、実際にはステートメントとして有効です。このセットは、

  • オペレーション・アンド・アサインド・アサインメントを含む代入式。
  • 前と後のインクリメントとデクリメントの式。
  • メソッド呼び出し( voidまたはnon- void )。
  • クラスインスタンス作成式。


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow