0

ここでは、実際の Java コンパイラの実装について言及しています。

スタックはC構造体として実装されていると思いますが、本当の意味は次のとおりです。

Javaはこの構造でどのように計算しますか? たとえば、1 つのローカル変数が文字列型またはポインター型で、もう 1 つのローカル変数が double または int であり、Java がこれらの変数を操作する必要がある場合、たとえば両方を追加する場合、最初に両方を同じ型に変換してから追加しますか? 、値を返しますか?

多かれ少なかれ次のようになりますか?

struct var {
    dataType type;
    union{
        char c;
        int i;
        double d;
        void *p;
    } value;
}

ここで、dataType はデータ型の列挙です。

例: 変数 A が double、変数 B が int、C が double であるとします。

C = A + B のバイトコードはどのように生成されますか? また、仮想マシンはこれらの異なるデータ タイプでどのように動作しますか?

4

2 に答える 2

1

Java は C ほど自由に型を強制しないため、「文字列と int を追加できるように変換する」ことはありません。

Java 型システムは通常、文字列の比較によって管理されます (ただし、ある概念レベルでは、そのような項目は最適化されていないことが多く、このレベルは大幅な単純化です)。

したがって、メソッドには署名があり、「.class」オブジェクトで文字列として表されます。

public static void main(String[] args) {
  ...
}

サインがあるだろう

main([Ljava.lang.String)V

これは、文字列 'java.lang.String' に強制変換できる型のオブジェクト 'L' の配列 '[' を取り、何も (void) 'V' を返さない名前 'main' を意味します。

したがって、一連のパラメーターを実行時にこれに渡すことができるかどうかを確認するには、オブジェクトの型をチェックして、文字列配列に「割り当て可能」かどうかを確認します。代入可能とは、型をスーパー クラスとして共有する、または型をインターフェイスとして持つ、またはスーパー クラスの 1 つがインターフェイスとして型を持つ、という手の込んだ言い方です。

このタイプのタイプ チェックにより、JVM は実際には JVM 内の要素に対して C スタイルのタイプ チェックを使用しません。ただし、この環境を実装する要素に対して C スタイルの型チェックを行います (意味がある場合)。

非常に興味がある場合は、仮想マシンの仕様を読んだり、JVM ソース コードをダウンロードしたりすることもできます。多くの場合、Java は (ポリモーフィズムのために) 静的な型チェックに依存できないため、C コンパイラの型検証は機能しません。

于 2013-03-12T21:14:59.530 に答える
1

浮動小数点 (倍精度浮動小数点数) と整数はまったく異なるデータ型であり、最近のすべてのプロセッサにはこれらのデータ型を処理するための特別な操作があります。また、Java バイトコードには、浮動小数点を追加するための追加オペランド (dadd) と、整数を追加するための追加オペランド (iadd) があります。

今あなたの質問に:

double A = 1;
int B = 1;
double C = B + A;

結果 C は double であるため、Java コンパイラーは単純に B を double に変換します。バイトコードは次のようになります。

dload_1    // load double A
iload_3    // load int B
i2d        // convert int to double
dadd       // add doubles 
dstore 4   // store result to C 
于 2013-03-12T20:36:46.920 に答える