在以下代码中创建了多少个对象?

hig*_*ger 2 java

class ClassA {
    void h() { }
}

class ClassB extends ClassA{

    public static void main(String[] args){
       ClassA a = new ClassA();
       ClassB b = new ClassB();
  }
}
Run Code Online (Sandbox Code Playgroud)

是的,每个人都认为它很简单,必须且绝对应该只创建两个对象.

但是在我读到"Think in Java,2nd Edition"之后,我认为它可能包含一些更有趣的东西.

在"Think in Java"中,有一句话:"当你创建一个派生类的对象时,它包含一个基类的子对象.这个子对象就像你创建了一个基类的对象一样通过它自己."

第2版​​是第278页.你也可以通过这个链接" http://www.codeguru.com/java/tij/tij0065.shtml "(标题为"初始化基类"的部分)看到它

bar*_*ley 13

应该是2.该main函数是静态的,因此它不需要对象.

ClassA a是一个对象,ClassB b是一个对象

编辑:ClassB不包含两个对象,因为extends是一种is-a关系,而不是一种has-a关系.(ta mik)

编辑:还有一个String[]由运行时系统创建的对象,并且可能在该数组中放置任意数量的字符串对象.我有意无视这些,但承认它们可能存在.(ta diveshpremdeep和Adam Goode)

最终编辑:为了确定创建了多少对象(通过程序,而不是运行时系统),您可以javap像命令行一样在命令行上使用该程序(如果test.java包含您的示例)

$ javac test.java
$ javap -c ClassB
Run Code Online (Sandbox Code Playgroud)

输出:

Compiled from "test.java"
class ClassB extends ClassA{
ClassB();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method ClassA."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   new #2; //class ClassA
   3:   dup
   4:   invokespecial   #1; //Method ClassA."<init>":()V
   7:   astore_1
   8:   new #3; //class ClassB
   11:  dup
   12:  invokespecial   #4; //Method "<init>":()V
   15:  astore_2
   16:  return

}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,只有两位字节码new(创建我假设的对象).一个用于上课ClassA,另一个用于上课ClassB.您可以注意到invokespecial之后调用该命令来调用构造函数,以及如何ClassA从类的构造函数中调用类ClassB的构造函数,但是在构造函数中没有创建新对象(它是默认的空构造函数).

调用javap -c ClassA显示一个同样无聊的构造函数,它调用Object的构造函数.

总结:它是在new堆上创建对象的字节码,而不是invokespecial仅填充new字节码分配的内存细节的字节码.

  • 没有创建"子对象".ClassB是一个ClassA(但有额外的B funkyness)而不是ClassA. (2认同)