如果有的话,在 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 中声明给定类的空对象字段时会发生哪些特定于类的操作?的主要内容,如果未能解决你的问题,请参考以下文章

java去掉实体类的空属性

在JAVA中啥是顶级类啊

Java类可以拥有的最大字段数是多少?

类的私有private构造函数 ,为什么要这样做

Java面向对象 类的成员之代码块的详解

java new一个对象的过程