Javaコンパイラはどのように型キャストを解析しますか?
-
03-07-2019 - |
質問
のような単純な式
(x) - y
は、 x
が型名であるかどうかによって異なる方法で解釈されます。 x
が型名でない場合、(x)-y
は x
から y
を減算します。ただし、 x
が型名の場合、(x)-y
は y
の否定を計算し、結果の値を x型にキャストします
。
典型的なCまたはC ++コンパイラでは、パーサーはtypedefまたはstruct宣言を処理するとすぐにそのような情報をレクサーに伝達するため、 x
が型であるかどうかの質問には答えられます。 (レベルのそのような必要な違反は、Cの設計の最も厄介な部分だと思います。)
しかし、Javaでは、 x
はソースコードの後半まで定義されない場合があります。 Javaコンパイラは、このような式をどのように明確にしますか?
Javaは使用前の宣言を必要としないため、Javaコンパイラには複数のパスが必要であることは明らかです。しかし、それは最初のパスが式の構文解析で非常にずさんな仕事をしなければならず、その後のパスで別のより正確な式の構文解析をしなければならないことを暗示しているようです。無駄だ。
もっと良い方法はありますか?
解決
私は私を満足させる解決策を見つけたと思います。 mmyersのおかげで、型キャストの構文の正式な仕様を確認する必要があることに気付きました。
あいまいさは、 +
および-
が単項演算子と二項演算子の両方であるために発生します。 Javaはこの文法で問題を解決します。
CastExpression:
( PrimitiveType Dimsopt ) UnaryExpression
( ReferenceType ) UnaryExpressionNotPlusMinus
( http://java.sunを参照してください。 com / docs / books / jls / third_edition / html / expressions.html#238146 )
そのため、キャストで ')'
の直後に '+'
および '-'
は明示的に禁止されていますプリミティブ型-先験的にコンパイラーによって知られています。
他のヒント
テストを行ったところ、次のコード:
Double y = new Double(0.1);
System.out.println((Double)-y);
コンパイルエラーが発生します:
演算子-Double、java.lang.Double
には適用できません。
-yをカッコで囲むと、正常にコンパイルされます。したがって、明らかにJavaは文法でそれを許可しないことでこの問題を解決します(それが正しい用語であれば、私はコンパイラの専門家ではありません)。