Java中内存中未初始化的静态变量

Java中内存中未初始化的静态变量,java,memory,static,Java,Memory,Static,在下面的示例中,内存是否分配给j?如果是这样,假设j永远不会被初始化,j的地址会在整个程序中改变吗 public class c{ private static String j; public c(){} .... } Java不是C。。。每个数据段(甚至静态变量)都会隐式初始化(通常为null或0),编译器不会接受未初始化的局部变量。首先,它是Java。因此,不要谈论地址访问和地址更改 为了程序的优化和效率,编译器代表用户执行所有这些操作 接下来,由于变量j被声明为

在下面的示例中,内存是否分配给j?如果是这样,假设j永远不会被初始化,j的地址会在整个程序中改变吗

public class c{
    private static String j;
    public c(){}
    ....
}
Java不是C。。。每个数据段(甚至静态变量)都会隐式初始化(通常为
null
或0),编译器不会接受未初始化的局部变量。首先,它是Java。因此,不要谈论地址访问和地址更改

为了程序的优化和效率,编译器代表用户执行所有这些操作

接下来,由于变量j被声明为静态变量,您无法决定地址,但其值在声明时将是永久的,即使在其块结束后,除非更改。(这意味着即使在块访问它并声明它已更改之后,它也不会丢失该值。)

它只有在程序终止后才会失去价值

在下面的示例中,内存是否分配给j

JVM将内存分配给包含
j
静态变量的帧。它将默认初始化为
null
。但是,
null
不引用任何堆节点

如果是这样,假设j永远不会被初始化,j的地址会在整个程序中改变吗

public class c{
    private static String j;
    public c(){}
    ....
}
没有具体说明,但根据我对JVM通常如何实现的理解,
j
的地址可能会改变


但是,除非程序试图从本机代码(或等效代码)访问
j
,否则它不会知道地址,也不会知道地址可能发生的更改

JVM将延迟加载一个类。在第一次引用该类时,将分配该类,并且将为所有静态字段设置yes内存。在这种情况下,j将保持“null”。类及其字段的分配位置将取决于JVM,尤其是所选的垃圾收集器

Java语言不像其他语言(如C语言)那样直接访问底层内存地址。是的,当垃圾收集器决定重新定位类时,底层内存地址可能会改变;一些地面军事系统不会重新安置课程,旧的地面军事系统甚至无法收回这些课程。需要注意的是,GC的任何移动对Java程序都是不可见的。也就是说,只要避免使用sun.misc.Unsafe,sun.misc.Unsafe就是Java 5中添加的JVM的后门


有关不安全的更多详细信息,这里有一个很好的概述。

您可以说它只指向
null
reference。Java中的内存是使用动态内存操作符分配的,即
new
操作符(某些类如字符串具有特权,可以使用
=
操作符进行初始化)。

Java没有“地址”的概念。你是在说引用id吗?-1.我不明白你在问什么。。。你能说得更清楚一点吗?@Deepanshu Bedi我的意思是referenceJava也没有内存分配的概念。方法中的局部变量也是这样吗?我很确定它们不是@BasileStarynkevitch,默认情况下它们没有初始化为0或null。事实上,局部变量在任何语言中都不会发生这种情况!帧,如在方法调用堆栈中,或其他地方?不是堆栈帧/本地帧。与类关联的框架。(实际上,JVM规范并没有讨论静态变量的表示方式/位置。它只是说,当静态变量(对象)未明确初始化时(默认为null),可以使用getStatic/putStatic字节码访问/设置静态变量。),它需要内存吗?@EricWang-是的。它需要的内存量与保存对已分配给变量的对象的引用所需的内存量相同。@EricWang-即…4字节或8字节,具体取决于JVM上引用的大小;即,它是特定于平台的,仅为我的2美分。因为j是一个字符串,是一个不可变的object,每次j的值改变时,jvm都会创建一个新对象,因此对j的引用也会改变。@holap-两个不同的东西。一个是指向对象的指针“j”的存储,另一个是对象本身的存储(如果有的话)。由于对象是不可变的,因此必须创建一个新的对象,但指针本身将只更改其值以指向新对象,而不是其存储位置。更改指针本身存储的位置往往只是为了JVM及其内存管理器的方便。