如果有的话,在 java 中声明给定类的空对象字段时会发生哪些特定于类的操作?
Posted
技术标签:
【中文标题】如果有的话,在 java 中声明给定类的空对象字段时会发生哪些特定于类的操作?【英文标题】:If any, what class specific actions happen when declaring an empty object field of a given class in java? 【发布时间】:2013-11-11 05:31:48 【问题描述】:想象一组层次结构的类,其中类 A 有一个字段 Class B,而类 B 有一个类 C 的字段。这些字段在每个类的构造函数中设置。
现在,如果我创建一个 X 类的对象实例,其中包含 A 类的字段“a”,其中“a”从未设置,并且保持为空:
如果有的话,对象“a”会发生哪些类特定的“动作”?它会从自己的领域中调用任何东西吗? B级或C级有反应吗?我想可能存在内存分配或类似情况,但我完全不确定。我问的原因是为了更好地了解数据流和应用程序中的操作顺序。
我试图找到这个问题的答案已经有一段时间了,但我似乎找不到正确的提问方式,因为这个问题与关于如何在 Java 中定义对象的基本问题有点太接近了。
【问题讨论】:
你为什么不直接用你的类写一个小程序,看看会发生什么 请编写一些代码,以便我们快速帮助您:) 没有对象“a”,因为该字段为空。那么“什么都没有”怎么能触发一个事件呢?你为什么认为事件被触发。根本没有触发任何事件。 B 类和 C 类不能“反应”,因为类不是听任何东西的活的对象。 @gefei 嗯,这就是我在大多数情况下所做的,但在这里我似乎无法想出一个让我亲眼看到结果的解决方案。虽然有一点经验,但我还有很多东西要学,我不知道如何检查一个对象是否被授予,即内存分配 @KjetilNordin "a" 不是 A 实例的容器。它是引用实例的容器。所有对象的引用以及空值都是长度为 32 或 64 位的值 - 就像 int 或 long int 一样。当使用new
创建对象时分配内存,而不是在将new
返回的引用写入变量时分配内存。否 new
- 没有内存分配。
【参考方案1】:
让我们假设以下类定义:
public class A
private B b;
public A()
b = new B();
public class B
private C c;
public B()
c = new C();
public class C
public C()
public class X
private A a;
public X()
现在假设正在执行以下 main:
public static final void main (String[] argv)
X x = new X();
这里在内存堆中创建了一个X
的实例,并且对该对象的引用存储在x
变量中。
由于在类构造过程中没有为a
变量赋值,因此没有创建A 的实例。 a
变量仍然占用内存中的空间,作为创建的 X
实例的一部分(换句话说,它仍然需要足够的空间来存储引用),但在这种情况下,a
是分配了null
值(来自Java Language Specification §4.12.5)
对于所有引用类型 (§4.3),默认值为 null。
现在让我们修改X
类如下
public class X
private A a;
public X()
a = new A();
如果我们要使用 X
的修改版本再次执行 main()
方法,那么作为构造过程的一部分,X
将导致创建 A
的实例,这将导致实例的B
被创建,这反过来会导致类C
的实例被创建。所有这些实例都会占用内存堆中的空间,并且对这些对象的引用将存储在它们各自的变量中。
【讨论】:
【参考方案2】:与其将引用类型变量视为持有“指针”,我认为将它们视为持有对象标识符更有帮助。如果X
是类类型Thing
的变量,则X
包含足以识别Thing
实例或从其派生的类的信息,或者足以说明它不存在的信息。尽管许多 Java 实现中的引用类型变量持有某种类型的指针,但并不要求它们这样做。想要访问超过 4 gigs 内存而不必使用 64 位对象引用的 Java 实现可以将所有对象大小四舍五入到下一个 16 字节的倍数,然后让每个非零对象引用存储一个缩放的偏移量到堆(因此位于堆开始上方 32016 字节的对象将存储数字“2001”[十进制]作为参考)。尽管 Java 没有说明与引用关联的位模式是什么意思,但它确实指定的一件事是,用于初始化数组槽和对象字段的位模式永远不会识别任何对象。
【讨论】:
以上是关于如果有的话,在 java 中声明给定类的空对象字段时会发生哪些特定于类的操作?的主要内容,如果未能解决你的问题,请参考以下文章