两个陈述之间有什么区别
int main()
{
A a = new A();
A a;
}
请解释这两个对象创建语句。
答案 0 :(得分:3)
第一个命令在堆栈(A a
)上分配一个变量,并在堆上初始化(new A()
)。
第二个只在堆栈上分配变量。它没有初始化,因此在您通过函数的返回值或调用类构造函数来分配它之前不能使用它。
备注:当您的程序被编译并运行时,它甚至不会与您编写的代码类似。变量在您需要之前加载。您上面的代码大致如下所示:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 8 (0x8)
.maxstack 1
.locals init ([0] class DERP.Program/A a, // This code here declares a local
// variable: A a;
[1] class DERP.Program/A b) // another local variable: A b;
nop
newobj instance void DERP.Program/A::.ctor() // This is: new A()
stloc.1 // this loads the new A() we created
// into A b; (stloc.1 means to store
// the last item we created into the
// local variable at index [1]
ret
} // end of method Program::Main
如果你没有完全理解每个命令是什么,那也没关系,但是我已经评论过它,试图让它尽可能地直截了当。由于我们从不将
A a
分配给任何东西,它只是位于本地堆栈上,闲逛,什么都不做。我们不能使用它,因为它没有指向任何对象。
在代码中有许多不同的原因,您可能会看到声明与实际分配分开。
例如,有时您需要在try {} catch {}
子句之外声明变量。假设您的类在其构造函数中获取值。你有一个从数据库中获取数据的函数。但是,由于它是一个DB调用,您希望捕获异常,如果抛出异常,则使用默认值初始化该类,而不是从DB调用返回的值。
由于在C#中使用作用域的方式,在try {} catch {}
内声明的变量在其外部无法访问,因此您需要在之前声明该变量。 >初始化。
答案 1 :(得分:2)
A a = new A();
这将创建一个A
类型的新对象。 a
的值将是A
的新实例。
A a;
这只会声明一种A
类型。 a
的值为null
。
答案 2 :(得分:0)
第一个创建一个新实例并将其分配给变量a
。
第二个不创建任何实例,因此a
为null
。
答案 3 :(得分:0)
在第一个语句中,它将创建一个A类的新对象实例,并将其分配给变量
在第二个声明中,它只是创建一个引用。
答案 4 :(得分:0)
只有你的第一个语句实际创建了一个新对象。其他人提到的第二个语句只是在你的堆栈上分配一个类型为A的变量。
第一个在manged堆上创建一个新对象,在堆栈上创建的类型A
的变量a上存储对它的引用。