2

我知道只要对象存在,字段就会粘在对象上,因此它们分配了一些内存,但是如果我不初始化某些字段并且不使用它们怎么办?例如:

public class TEST {
   public static void main(String[] args) {
      Foo C = new Foo(5, 7);
      Foo D = new Foo(5);
      ...
}

public class Foo{
   private int A;
   private float B;

   public Foo (int A, float B){
      this.A = A;
      this.B = B;
    }
    public Foo (int A){
        this.A = A;
    }
    ...
}

C消耗更多的内存D吗?

4

4 回答 4

7

Java 中的字段总是被初始化的。基元初始化为 0 或false,引用(和数组)初始化为null

此外,一旦您声明了一个字段,该字段将始终在每个实例中占用相同的空间。引用只占用与指针一样多的空间,但被引用的对象可能会占用额外的内存。

于 2013-02-16T17:55:13.307 回答
1

您没有在构造函数中初始化字段这一事实并不意味着它们没有被初始化。

当您使用new运算符创建类的实例时,会创建对象并为新创建的实例分配内存,以及该类的所有实例字段及其所有超类,并使用它们的默认值初始化它们。

所有这些都发生你的构造函数被调用之前。所以,是的,在这种情况下,两者都CD分配相同的内存。

现在考虑这种情况,您的字段不是原始的,而是对其他实例的引用(例如,Integer而不是int)。Integer在这种情况下,默认值为null。如果您为一个引用初始化它C,而不是为D,那么该C引用将拥有更多内存(为引用字段创建的实例的额外内存将在那里。)。

于 2013-02-16T17:49:34.643 回答
1

首先,对风格的琐碎评论。代码在我看来是 Java 的。所以所有的变量都应该是小写的。然后,对于您的问题,在您的示例中,对象 C 和 D 消耗的内存量相同。

这些字段是原始类型,堆上的一个 Foo 对象将占用 4 个字节用于 int,另外 4 个字节用于 float。即使您不初始化它们,它们也会采用默认值(由编译器设置)。

再深入一点,Foo 对象在 32 位 JVM 上将消耗 16 个字节。

8 个字节用于标头(对象 id、对类对象的引用、锁等),8 个字节用于字段(int 和 float)。

有关更多详细信息,请参阅这篇不错的文章

于 2013-02-16T18:11:16.147 回答
0

new分配内存。Sizeof(Foo) 是常量,因为它完全由原始类型组成。

如果您在 Foo 中添加一些对象类型的属性,则无论您是否分配它们,消耗的大小都会发生变化。

public class Foo{
   private int A;
   private float B;
   private Date  C;

   public Foo (int A, float B){
      this.A = A;
      this.B = B;
      this.C = new Date();
    }
    public Foo (int A){
        this.A = A;
    }
    ...
}

public class TEST {
   public static void main(String[] args) {
      Foo C = new Foo(5, 7);
      Foo D = new Foo(5);
      ...
   }
}

在这种情况下,D 消耗的内存比 C 少。

于 2013-02-16T17:49:06.993 回答