Should be 2. The main function is static so it doesn't need an object.
ClassA a is an object and ClassB b is an object
EDIT: ClassB doesn't consist of two objects because extends is an is-a relationship and not a has-a relationship. (ta mik)
EDIT: There is also the String[] object that is created by the runtime system, and potentially any number of string objects place within that array. I am purposefully ignoring these but acknowledge their possible existence. (ta diveshpremdeep and Adam Goode)
FINAL EDIT: In order to determine how many objects are created (by the program, not the runtime system) you can use the javap program on the commandline like so (if test.java contains your example)
$ javac test.java
$ javap -c ClassB
output:
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
}
As you can see, there are only two bits of bytecode that are new (which creates objects I assume). One for class ClassA and the other for class ClassB. You can note that the invokespecial command is invoked afterwards to call the constructor, and also how class ClassA's constructor is called from class ClassB's constructor, but no new object is created inside the constructor (it is the default empty constructor).
calling javap -c ClassA shows an equally boring constructor which invokes the constructor for Object.
In summary: It is the new bytecode which creates objects on the heap, not the invokespecial which merely fills in the details of the memory allocated by the new bytecode.