2017-11-12 3 views
0

効果的な理由最終変数はスイッチブロックではなく機能に対して機能しますか?Java 8:効果的な理由スイッチブロックで最終変数が機能しないのですか?

次の例は、コンパイルエラー

String comparing = " "; 
    String effectivelyFinal = "Hello "; 
    switch(comparing){ 
     case effectivelyFinal : 
      System.out.println("Are equal"); 
      break ; 
     default : 
      System.out.println("Are not equal"); 
    } 
    Predicate<String> areEqual = s -> s.equals(effectivelyFinal); 
+5

スイッチは定数を比較するため、他の変数と比較することはできません。 – Walfrat

+0

@Walfrat Java SE 8では、ローカルクラスは、最終的にまたは効果的に最終的な囲みブロックのローカル変数とパラメータにアクセスできます。値が初期化された後に決して変更されない変数またはパラメータは事実上最終的です。なぜスイッチは効果的に変数を見ることができないのですか? – Aguid

+0

コンパイル時に知っておく必要があります...そして、単純な 'if-else'ではなく' switch-case'をここで使用している理由を理解できません。 – AKSW

答えて

3

にコードを与え、スイッチケースを使用する場合と比較することができる単にためのみ定数式をコンパイルしません。ラムダ(無名関数)では、これに限定されるものではありません。

ただ、これ以上の混乱を明確にするために、効果的に最終は、単にその値ある変数またはパラメータを意味し、それが初期化された後は変更されませんが、あなたはそれを変更することができますよう、必ずしもそれ定数式ことはありません。 ;その場合、それはもはやの効果的な最終的なではないので、なぜそれがスイッチケース式として許可されていないのですか。

2

スイッチラベルはSection 14.11 of the JLSごとに、3種類のいずれかである必要があります

SwitchLabel: 
    case ConstantExpression : 
    case EnumConstantName : 
    default : 

Section 15.28することにより、定数式は、とりわけ、することができ、

単純名(§6.5。 6.1)を参照してください(§4.12.4)。

あなたの単純な名前は定数変数を参照していないため、許可されていません。

ラムダの場合、JLSではこのような制限はありません。

+0

興味深いことに、 –

+0

私はバージョン3に戻ってきましたが、それでも 'ConstantExpression'と言います。 –

+0

https://docs.oracle .com/javase/specs/jls/se7/html/jls-18.htmlあなたの例のように "SwitchLabel"を探します。 –

1

effectivelyFinalは他の文字列に再割り当てできるので、実際はfinalではありません。

コンパイラは約compile-time constantsであり、実効定数ではありません。 Java言語仕様では、この上の

の詳細:あなたのコードは、変数にfinalキーワードを追加することによって更新する場合、それはcompile-time constantとコードになるhttps://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11

はようになりましたeffectivelyFinal変数が本当にfinalあなたができないようでコンパイルしますもうその値を変更してください。

String comparing = " "; 
final String effectivelyFinal = "Hello "; 
switch(comparing){ 
    case effectivelyFinal : 
     System.out.println("Are equal"); 
     break ; 
    default : 
     System.out.println("Are not equal"); 
} 
Predicate<String> areEqual = s -> s.equals(effectivelyFinal); 

ラムダまたは通常の機能の場合、このような制限はありません。

関連する問題