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

Java 仅定义对象时会发生什么情况?,java,class,object,memory,Java,Class,Object,Memory,我想知道当一个对象在内存级别被定义,但没有初始化时会发生什么 例如: public class MainClass { public static void main (String[] args){ Object foo; } } foo是否指向内存空间? 这种行为在不同的编程语言之间会发生变化吗 提前谢谢 编辑:我知道对象在使用时会指向null,但是我想知道在对象被定义之后,还没有实例化的时候会发生什么。 在这种情况下是否有对内存的引用?在java中,foo在类中定义时将指向“nu

我想知道当一个对象在内存级别被定义,但没有初始化时会发生什么

例如:

public class MainClass {
 public static void main (String[] args){
  Object foo;
 }
}
foo是否指向内存空间? 这种行为在不同的编程语言之间会发生变化吗

提前谢谢

编辑:我知道对象在使用时会指向null,但是我想知道在对象被定义之后,还没有实例化的时候会发生什么。
在这种情况下是否有对内存的引用?

在java中,foo在类中定义时将指向“null”,
foo在函数中定义的地方不会指向任何东西。

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

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

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
<>这与C或C++有很大的不同,在这里,代码>对象FO;
实际上是在堆栈上分配的本地对象。Java从不在堆栈上分配对象,只分配基本类型或指针

我想知道当一个对象在内存级别被定义,但没有初始化时会发生什么

假设我们在这里讨论的是Java

首先我必须纠正你不正确的描述。(原因显而易见……)

这不是定义对象。相反,它是在声明一个变量。标识符
foo
表示一个变量。由于变量的类型(在本例中)是引用类型的
Object
,因此该变量可能包含对Java对象的引用
null

foo
是否指向内存空间

答案有点复杂

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

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

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

    • 对于作为参数或catch变量的变量,Java语言语义确保始终初始化该变量。。。所以这是没有意义的

    • 对于局部变量,JLS在为其赋值之前不会说明它包含什么。你可以说这个值是不确定的但是JLS(在运行时,JVM的类文件验证器)确保程序不能使用处于不确定状态的局部变量。(在Java代码中,读取未被明确赋值的变量是一个编译错误。)因此,变量实际包含的内容实际上没有区别

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

这种行为在不同的编程语言之间会发生变化吗


呃。。。对例如,在C和C++中,程序可以使用未初始化的指针变量的值。随后发生的行为未指明

这里只有一个变量。没有对象。在java中,您只需要引用“nothing”。没问题。但是,在C++中,在这种情况下,你会得到一个真实的对象。这是为了回答问题的第二部分。不带任何修饰符的方法中的变量是在堆栈上创建的用作成员,它将被初始化为
null
。如果在方法中使用,您必须自己初始化
foo
,在我的测试中,可能会以其他方式运行代码。C++处理的东西有点不同。这里,
objectfoo
将导致调用默认构造函数,无论它位于何处。我认为这有点误解。如果只声明而不初始化,那么像
foo==null
这样的检查也不会编译(变量未初始化),至少在我的测试中是这样。在第二句话中(“默认情况下,它们不指向任何东西(
null
),[…])。可以理解,
foo==null
返回
true
“指向引用”可能更准确。此外,没有任何内容不等于
null
。由于单位化变量不会分配给
null
,因此未指定未初始化变量实际包含的实际值。但是,一旦字节码中分配了一个插槽,JVM将始终将其初始化为0。这并不重要,因为使用这样一个变量的代码是无法编译的。正如您已经说过的,在Java中,对象更像是引用。正如前面所说的,java对象最好用C++中的指针来描述。但是为了增加完整性,你不必在C++中创建指针。只声明
对象foo,C++将调用默认构造函数。@ toBiasBr.OSAMLE——我没有试图解释C或C++声明和java之间的所有区别。这将是一个不同的问题(而且太宽泛了!)。