0

我在这里指的是实际的java编译器实现:

我猜堆栈是作为C结构实现的,但我真正的意思是:

java如何用这种结构计算?例如,如果一个局部变量是字符串或指针类型,而另一个是双精度或整数,而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 字节码还有一个用于添加浮点的添加操作数 (dadd) 和一个用于添加整数的添加操作数 (iadd)。

现在回答你的问题:

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

由于结果 C 是双精度,Java 编译器将简单地将 B 转换为双精度。字节码看起来像这样:

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 回答
1

Java 不像 C 那样自由地强制类型,因此从来没有“以添加它们的方式转换字符串和 int”。

Java 类型系统通常通过字符串比较来管理(然而,在一个概念级别上,此类项目通常被优化掉,而这一级别是一种粗略的简化)。

所以一个方法有一个签名,它在“.class”对象中表示为一个字符串。

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

会有签名

main([Ljava.lang.String)V

意思是一个名字'main',它接受一个类型为'L'的对象'L'的数组'[',可以强制转换为String'java.lang.String'并且什么都不返回(一个void)'V'。

因此,要查看是否可以在运行时将一组参数传递给 this,检查对象的类型以查看它是否“可分配给”字符串数组。可赋值是一种奇特的说法,将类型共享为超类,或者将类型作为接口,或者其中一个超类将类型作为接口。

由于这种类型检查,JVM 实际上并没有对 JVM 中的元素使用 C 风格的类型检查;但是,它确实对实现此环境的元素进行 C 样式类型检查(如果这对您有意义的话)。

如果你很好奇,可以阅读虚拟机规范,甚至可以下载 JVM 源代码。您会发现 Java(由于多态性)在许多情况下不能依赖静态类型检查,因此 C 编译器类型验证无论如何都不起作用。

于 2013-03-12T21:14:59.530 回答