Oop 这个对象初始化时会发生什么?

Oop 这个对象初始化时会发生什么?,oop,Oop,我按照下面的代码进行对象初始化: namespace PatternPractice { public class TestClass { private DecoratorClass decoratorClass; public TestClass() { } public void addTest() { decoratorClass = new DecoratorClass(); testMethod(

我按照下面的代码进行对象初始化:

namespace PatternPractice
{
 public class TestClass
 {
    private DecoratorClass decoratorClass;
    public TestClass()
    {

    }

    public void addTest()
    {
        decoratorClass = new DecoratorClass();
        testMethod(decoratorClass);
    }

    public void testMethod(DecoratorClass d)
    {
        Console.WriteLine("Am doing to explain my question.");
    }
   }
}
我有以下问题:

a。什么是装饰类变量?对创建此变量的内存位置的引用,还是其他内容

b。在addTest()方法中,我初始化了这个decoratorClass,它现在变成了什么,对对象的引用,还是其他什么

c。如果这变成了对对象的引用,那么为什么我们要在要通过引用传递的参数中使用ref呢。如果decoratorClass不是一个参考或其他东西,这个问题就不成立了

d。在testMethod()方法中,我知道创建并传递了decoratorClass的副本,它是引用还是其他什么

我对所有这些在运行时(ASP.NET或JVM等)结束时是如何发生的有点困惑,基本上与内存中的对象创建有关

是否有任何文章可以解释运行时如何创建对象以及如何将它们分配给内存


谢谢你的帮助。如果DecoratorClass是一个类,那么是的,它是一个引用。如果它是一个结构,那么类TestClass包含DecoratorClass的整个实例

b。见“a”

c。ref用于更改实际引用,而不仅仅是它所引用的对象


d。如果DecoratorClass是类,那么只复制对它的引用并传递给testMethod。如果是struct-则复制整个实例并将其传递给testMethod。在类的顶部,Decoratorclass只是一个没有分配内存的变量。对象是在堆上而不是在堆栈上创建的

b。在testmethod中,您现在已经为堆上的这个DecoratorClass对象分配了内存,并且您的变量DecoratorClass成为对堆上分配的内存的引用

c。Ref参数主要用于传递值类型,如(int、long、char等)。如上所述,如果要更改对象在内存中引用的内容,可以使用Ref传递对象(引用类型)。现在可以更改该对象引用的内容


d。如上所述,仅传递引用。因此,对该对象所在位置的引用是在堆上传递的,在这样传递它时,您不能更改它。如果使用Ref传递它,您可以更改它引用的内容。现在您只能更改它包含的数据。

值类型和引用类型的基本概念

任何类型的变量(无论是值类型还是引用类型)在声明时都会推送到堆栈上

然而,它们之间的区别是,对于值类型,对象的值存储在堆栈上。然而,对于引用类型,堆的地址存储在堆栈上

因此,请考虑以下陈述:

int a;
DecoratorClass decoratorClass;
现在,当这些语句运行时,这是堆栈:

STACK:

Variable        Value
a                 0     // Since ints are assigned to 0 by default
decoratorClass    NULL
现在如果您尝试访问decoratorClass,例如
decoratorClass.memberVariable=xyz等。然后您将得到一个NullPointerException。
这是因为decoratorClass只声明为未初始化。只有在调用构造函数时,它才会被初始化

因此,当下面的语句运行时:

decoratorClass = new DecoratorClass();
1) 在堆上的特定位置(地址)分配内存。以字节为单位分配的内存量取决于类定义(成员变量)

2) 现在,由于为对象分配了一些内存,堆栈将使用内存地址进行更新

STACK:

    Variable        Value
    a                 0     // Since ints are assigned to 0 by default
    decoratorClass  xEEEE00
现在,如果尝试访问decoratorClass.memberVariable,将不会得到NullPointer异常,因为实例已初始化,并且在堆栈上分配了内存位置

现在回答您的问题:

a.什么是装饰类变量?对创建此变量的内存位置的引用,还是其他内容? b.在addTest()方法中,我初始化了这个decoratorClass,它现在变成了什么,对对象的引用,还是其他什么

Ans: declaration语句运行时,decoratorClass变量将被推送到堆栈上。 堆栈上的值(应该是堆上的地址)将为空,因为堆上尚未分配内存。 调用构造函数时,将在堆上分配内存。 堆栈现在将包含堆上的地址

在回答c之前,让我先回答d,因为我相信这样理解会更简单

d.在testMethod()方法中,我知道创建并传递了decoratorClass的副本,它是引用还是其他什么

Ans: 根据我上面给出的解释,在方法testMethod(DecoratorClass d)中,d是testMethod()的局部变量。但d中的值是多少(即堆栈上的值)?这是decoratorClass的地址。因此局部变量d指向同一堆,因此访问d的memberVariable将给出与访问decoratorClass的memberVariable相同的值

现在,如果您创建一个新的DecoratorClass并将其分配给d,它将不会更改DecoratorClass。所以d可能会指向EE06,但decoratorClass仍然会指向EE00

现在让我们转到c

c.如果这成为对对象的引用,那么为什么我们要在要通过引用传递的参数中使用ref。如果decoratorClass不是一个参考或其他东西,这个问题就不成立了。 Ans: 让我们考虑同样的方法TEST方法(REF DeCalaCype D)。由于您将d作为ref传递,因此它不再是一个局部变量,而是同一个变量

现在,如果您创建一个新的DecoratorClass并将其分配给d,它将更改DecoratorClass。因此d将指向EEEE06,但是decoratorClass也将指向EEEE06,因为这两个变量在堆栈上是相同的

有关按参考v/s pass objec传递对象的更多详细信息
STACK:

    Variable        Value
    a                 0     // Since ints are assigned to 0 by default
    decoratorClass  xEEEE00