Kor*_*gay 56 php c# java oop static-members
说你有课,
class Foo
{
public static bar;
}
Run Code Online (Sandbox Code Playgroud)
当你说:
new Foo();
Run Code Online (Sandbox Code Playgroud)
我可以想象,在内存中,为这个对象保留了一个空间.
......当你再说一次时:
new Foo();
Run Code Online (Sandbox Code Playgroud)
...现在你有另一个可用于该物体的空间.
但是,静态场的确切位置在哪里?
我真正想要学习的是:
对象的引用如何引用它们引用的对象的相同字段?
Dan*_*ker 105
虽然类型系统的确切细节是依赖于实现的,但让我更详细地说明它取决于它并且您不应该关心.我将根据Jeffrey Richter的书籍CLR by C#和Hanu Kommalapati等人的CLR创建运行时对象的文章描述它在Microsoft的实现(.NET)中是如何工作的.(原MSDN 2005年5月号).
假设你有一节课:
class Foo
{
// Instance fields
string myBar = "Foobar";
int myNum;
// Static fields
static string bar = "Foobar";
static int num;
}
Foo myFoo = new Foo();
Type typeOfFoo = typeof(Foo);
Run Code Online (Sandbox Code Playgroud)
实例字段在哪里生效?
无论何时说new Foo(),都为对象实例分配和初始化空间,并调用构造函数.此实例在下图中显示为Foo的实例.如实例只包含类(在这种情况下的实例字段myBar和myNum),并在运行时(使用的堆了两个附加字段分配的对象Sync block index和Type handle).类型句柄是指向Type描述实例类型的对象的指针,在本例中为Foo类型.
再说new Foo()一次时,会分配新空间,该空间将再次包含该类型实例字段的空间.如您所见,实例字段与对象实例相关联.
运行时将每个实例字段放在距对象数据开头的固定偏移处.例如,myBar可能住在偏移+4.实例字段的地址只是对象的地址加上字段的偏移量.
静态字段在哪里生活?
C#和Java中的静态字段不与任何对象实例关联,而是与类型关联.类,结构和枚举是类型的示例.只有一次(每种类型)分配一些空间来保存静态字段的值.为Type描述类型的结构中的静态字段分配空间是有意义的,因为Type每种类型也只有一个对象.这是C#和Java采用的方法.
在Type对象1时的类型由运行时加载的被创建.此结构包含运行时能够分配新实例,调用方法和执行转换等所需的各种信息.它还包含了静态字段的空间,在这种情况下bar和num.
运行时将每个静态字段放在距类型数据开头的某个偏移处.每种类型都有所不同.例如,bar可能生活在偏移+64.静态字段的地址是Type对象的地址加上字段的偏移量.这种类型是静态知道的.

1)在Microsoft .NET中,多个不同的结构描述了一种类型,例如MethodTable和EEClass结构.
Ree*_*sey 16
这完全取决于有问题的实施.对于C#和Java,允许运行时确定存储变量内存的位置.对于C和大多数编译语言,编译器进行此确定.
话虽这么说,但实际上并不重要.它由规范确定的用法,因此您可以自由地使用知道行为的变量.
这种语言因语言而异,甚至可能因平台而异.
例如,在.NET端,静态成员与管理EEClass定义"关联",管理定义可以是堆分配的OR或 "任何地方"分配的成员(C#规范不指定堆/堆栈行为,它是一个实现VM的细节)
我只熟悉 C#,这是我对它的理解:
然后您的程序启动,它将所有相关程序集加载到 AppDomain 中。加载组装时,将调用所有静态构造函数,包括静态字段。它们将住在那里,卸载它们的唯一方法是卸载 AppDomain。
可能存在异常,但对于引用类型,new-keyword通常会在名为"heap"的内部数据结构中创建一个对象.堆由CLR(公共语言运行时)管理.无论是静态实例还是实例成员或局部变量都没有区别.
静态成员和实例成员(没有关键字的成员)之间的区别在于static,每个类型(类,结构)只存在一次静态成员,每个实例(每个对象)存在一次实例成员.
它只是静态的参考; 此区别不适用于引用的对象(除非该对象是值类型).静态成员,实例成员和局部变量都可以引用同一个对象.