在下面的例子中,内存分配给j?如果是这样,假设j永远不会被初始化,整个程序中j的地址是否会改变?
public class c{
private static String j;
public c(){}
....
}
答案 0 :(得分:2)
JVM将延迟加载一个类。在第一次引用该类时,将分配该类,并且将为所有静态字段布置内存。在这种情况下,j将保持' null'。将分配类及其字段的位置取决于JVM,最具体地说是选择的垃圾收集器。
Java语言不像其他语言(如C语言)那样直接访问底层内存地址。是的,如果/当/垃圾收集器决定重新定位类时,底层内存地址可能会改变;一些地方选区不会重新安置课程,旧课程甚至无法重新开课。值得注意的是,GC的任何移动对Java程序都是不可见的。也就是说,只要你避免使用sun.misc.Unsafe,sun.misc.Unsafe就是Java 5中添加的JVM的后门。
有关不安全的详细信息,此blog有一个很好的概述。
答案 1 :(得分:1)
首先,它是 Java 。因此,没有谈论地址访问和地址变更。
编译器代表用户完成所有这些操作,以优化和提高程序效率。
接下来,由于变量j已被声明为静态,因此您无法确定地址,但除非更改,否则即使在其块结束后,其值仍将是永久性的。 (这意味着即使在访问它并声明它发生变化的块之后它也不会丢失该值。)
在程序终止后它才会失去价值!
答案 2 :(得分:1)
在下面的例子中是分配给j?
的内存
内存由JVM分配给包含j
静态变量的帧。并且将默认初始化为null
。但是,null
不引用任何堆节点。
如果是这样,假设j永远不会被初始化,整个程序中j的地址是否会改变?
没有指定,但基于我对JVM通常如何实现的理解,是j
的地址可能会改变。
但是,除非程序试图从本机代码(或等效代码)访问j
,否则它将不会知道该地址或可能的更改。
答案 3 :(得分:0)
你可以说它只会指向null
参考。 Java中的内存是使用动态内存运算符分配的,即new
运算符(类似String的某些类具有可以使用=
运算符初始化的特殊权限)。
答案 4 :(得分:-1)
Java不是 C ...每个数据块(甚至是静态变量)都被隐式初始化(通常为null
或0),并且编译器不会接受未经过本地化的本地化变量。找到this explanation