私は最近のJavaを勉強し始めている、とだけ言語の一つの特徴を理解することができませんでした。
私は、下のコードを書くとき、私はすべてのエラーを得ることはありません(と分別Iはいけません!):
byte b = 10 * 2
私は、次のコードを入力するときただし、コンパイラはエラーをスローします。
int i = 10;
byte b = i * 2
コンパイラは、上のチェックを実行することができたとき10 * 2
、それは以下の範囲よりもだことを確実にするためにbyte
、なぜそれはまた、上のチェックを実行することはできませんi * 2
、それは以下の範囲よりもだかどうかbyte
?
それはビットの下位レベルの表現とは何か、またはメモリに関連する何かを持っていますか?
私は何もJava固有のポジティブないんだけど、現代の任意のコンパイラは、一定の折り全く定数で表現を「折る」ことを実行することになります。すなわち、20から10の* 2折り目、それはあなたが入力したかのようにコンパイラの扱いので、byte b = 20;
コンパイラがしようとすると、変数のために最適化することは、本当に実用的ではありません。でも、あなたの提供された例では、見て、それを知ることが比較的簡単ですが、i
ある10
コンパイラは最適化しようという、何を知っているならば、i
だった、それはそれ自身のシンボルテーブルを維持しなければならないであろうと、本質的に通訳になります。Javaは、プリコンパイル言語であるので、これは目的に反し。
エラボレーション:
コンパイラとインタプリタの違いがあります。コンパイラは、入力として、ソースコードを取り込み、舞台裏でマシンコードを書き込みます。そのマシン・コードが実行を取得すると、操作/実行/計算が実行されます。Javaはそれのコンパイラは、多くの計算をやっていないので、それだけで、Java仮想マシン上で実行することができますマシンコードを書いている、コンパイル言語です。一方、Pythonは、インタプリタ言語です。あなたはPythonのプログラムを実行すると、それがために任意の型変換を実行しようとしませんi * 2
、それは評価さをactuall後までi * 2
。
さて、時々コンパイラは、スマート取得しようとして築いてきた「最適化」。これが意味することの代わりに、いくつかの操作を行いますマシンコードを書く、それはそれがどうなるか知っているので、彼らは少ない命令でマシンコードを書く(コンパイラがないようであるいくつかのことを達成するための計算を)。あなたの例では、数10を格納し、ライトマシン命令は、番号2を保存するのではなく、乗算彼らは、その結果を格納し、コンパイラの缶、複数の10と2、そしてちょうどその結果を格納するための機械命令を記述します。
私たちは、変数を導入すると、その変数が何であるかを最適化し、図のように、コンパイラのために難しくなります。実際のコンパイルプログラム(Javaコンパイラは)私は今数10を保持する変数であることを覚えておく必要があります。私達はちょうど私たちは私が* 2を割り当てることができます知って最適化したい場合byte
、それはその時点で- 、それはコンパイラが、それは後の表現でバイトに割り当てられますことをオフのチャンスにすべての単一の整数型変数を覚えておく必要がありますを意味しますコンパイラは余分な計算を費やしていると、本当にどんな恩恵を与えないこと(余分な作業をコンパイルするために)最適化は本当に価値がないです。(上述の)シンボルテーブルは、基本的変数と何それらの値はを記憶するテーブルです。