仅定义对象时会发生什么?

时间:2019-01-11 09:55:57

标签: java class object memory

我想知道在定义但未初始化对象时在内存级别会发生什么。

例如:

public class MainClass {
 public static void main (String[] args){
  Object foo;
 }
}

foo 是否指向内存空间? 这种行为会在不同的编程语言之间改变吗?

谢谢。

编辑:我知道使用该对象时,该对象将指向 null ,但是我很想知道在定义该对象之后(尚未实例化)该怎么办。 在这种情况下是否有对内存的引用?

3 个答案:

答案 0 :(得分:2)

  

我想知道在定义但未初始化对象时在内存级别会发生什么。

让我们假设我们在这里谈论Java。

首先,我必须纠正您的错误描述。 (出于显而易见的原因...)

这不是定义对象。而是声明一个变量。标识符foo表示变量。由于变量的类型是(在这种情况下)Object,它是引用类型,因此变量可以包含对Java对象的引用或 null。 >

  

foo是否指向存储空间?

答案有点复杂。

  • 如果变量已初始化,它将指向某个对象或包含null

  • 如果未初始化变量,则取决于我们正在谈论的变量类型:

    • 对于类(静态或实例)的字段,未明确初始化的变量默认初始化null

    • 对于作为参数或catch变量的变量,Java语言语义确保始终对变量进行初始化...因此,这没有什么意义。

    • 对于局部变量,JLS在分配值之前不会说出它包含的内容。您可以说该值是不确定的。 但是 JLS(在运行时,JVM的类文件验证程序)确保程序不能使用处于不确定状态的局部变量。 (读取未明确赋给的变量是Java代码中的编译错误。)因此,变量实际所包含的内容确实没有区别。

请注意,在纯Java中,变量永远不可能包含赋值或初始化未设置的值。因此,变量永远不能引用随机存储器地址。 (如果使用本机代码,则代码可能会破坏变量以包含任何内容。但是请不要故意这样做,因为这可能会使JVM崩溃。)

  

这种行为在不同的编程语言之间会改变吗?

Err ...是的。例如,在C和C ++中,程序可以使用尚未初始化的指针变量的值。发生的行为是未指定

答案 1 :(得分:1)

在java中,foo在类中定义时将指向“ null”, 和foo将指向在函数中定义的任何内容。

答案 2 :(得分:1)

在Java中,您可以将对象变量视为指针。默认情况下,它们不指向任何内容,仅分配指针本身(例如,堆栈上的8个字节)。

通过分配对象并分配给变量,可以使其指向对象的实际实例:

let gameTable = document.getElementById('gameBoard');
gameTable.setAttribute('disabled', true);

这与C或C ++根本不同,其中的Object foo; // points to nothing (and may not be used) foo.toString(); // compile error: The local variable obj may not have been initialized foo = new Object(); // points to an instance of a new Object foo = null; // again points to nothing, but is now initialized foo.toString(); // will compile, but throw NullPointerException at run time 实际上是在堆栈上分配的本地对象。 Java永远不会在堆栈上分配对象,只能分配原始类型或指针。