gpt4 book ai didi

java - 在循环 block 中声明变量

转载 作者:行者123 更新时间:2023-12-01 06:45:29 25 4
gpt4 key购买 nike

class Sample {

int a;

public void abcx() {
for (int i = 0; i < 5; i++) {
if (i % 2 == 0) {
int b = i;
}
}
}
}

多久分配一次b

最佳答案

请看一下 nhahtdh 的回答。很好,因为它引用了 JLS 的相关章节。

我不会删除这个答案,因为我希望它能给你一些提示,让你自己找到这样的答案(或者至少是好的猜测),以应对 future 的问题。它还可能为您的示例代码提供一些额外的解释。

首先:如果涉及到“Java 在 XYZ 情况下会做什么”,您应该经常问“我的 JVM 在 XYZ 情况下会做什么”。如果你想回答有关Java本身的问题,应该可以引用Java Language Specification

编辑:请参阅 nhahtdh 答案以获取此引用。

您的示例代码中发生了什么?

我想您能做出的最佳猜测是使用 Java 字节码。现在,加载对象/数据结构/基本类型和分配对象/数据结构/基本类型之间存在差异。

分配一个对象意味着你给它一些可以存储它的空间。它只是一个占位符。使用 aload_0 加载意味着对象引用被推送到操作数堆栈上。下一个操作将从操作数堆栈中获取其操作数。

javac Sample.java
javap -c Sample.class

给你Java字节码:

Compiled from "Sample.java"
class Sample {
int a;

Sample();
Code:
0: aload_0 // load int a
1: invokespecial #1 // Method java/lang/Object."<init>":()V (every class is a child class of Object)
4: return

public void abcx();
Code:
0: iconst_0 // get 0 on stack
1: istore_1 // store 0 to variable 1 (int i=0)
2: iload_1 // load 0 from variable 1 (load 0 from i)
3: iconst_5 // load 5 from
4: if_icmpge 21 // i<5 (21 means: jump to line 21 if i >= 5)
7: iload_1 // load i
8: iconst_2 // load 2
9: irem // i%2
10: ifne 15 // if(i%2!=0) jump to line 15
13: iload_1 // load i
14: istore_2 // b=i
15: iinc 1, 1 // i++
18: goto 2 // back to loop condition
21: return
}
  • aload_0:在操作数堆栈上加载对象引用 ( source )
  • iconst_n:这些用于将常量整数 0 到 5 压入堆栈。 (source)
  • istore_1 :将栈顶的整数存入变量1
  • 调用特殊:( source )
  • if_icmpge :将顶部的两个整数从堆栈中弹出并进行比较。如果 value2 大于或等于 value1,则执行分支到地址 ( source )
  • irem:从操作数堆栈中弹出两个 int,将 value2 除以 value1(即 value2/value1),计算余数并将 int 余数推回堆栈 ( source )

回答您的分配问题

我不确定正确答案。我猜用户 Budda 可能是对的: 编辑:不,佛陀错了。但让我们解释一下为什么这是一个很好的猜测。

It is allocated once when i is 0, and then when i is 2 and again when i is 4. So 3 in total.

一旦}关闭,b的范围就结束了。因此它应该被垃圾收集器“删除”,因为b没有对它的引用。但你必须考虑到primitive data types不在堆上,只有堆由垃圾收集器管理 ( source )。

当您查看上面的字节代码时,您可能会注意到 b 仅在一行中发生了更改 (istore_2)。因此,您可能想查看进程的内存布局。

我不确定以下内容是否也适用于 Java 程序,但适用于 x86 中的进程。进程在内存中看起来像这样:

enter image description here来源:My blog :-) 这是操作系统类的作业。

您可以看到原始数据类型在内存布局中有自己的部分。所以我想它会在类加载时分配一次。但我无法向您提供这一猜测的来源,而且我对此也不确定。

编辑:另请参阅The Architecture of the Java Virtual Machine .

关于java - 在循环 block 中声明变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16314417/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com