12

Possible Duplicate:
How can a class have a member of its own type, isnt this infinite recursion?

The Code:

public class Test2{
    private Test2 subject = new Test2(); //Create Test2 object in Test2
    private int num;
}

The Questions:

  1. Why does Java permit the above code to be executed, but C++ doesn't?

  2. Does the code above create infinite number of objects? Since Test2 itself contains a Test2 object which again contains a Test2 object which itself has a Test2 object and so on.

Community
  • 1
  • 1
caramel1995
  • 2,968
  • 10
  • 44
  • 57

6 Answers6

18

The key difference between the two languages regarding your problem is that Java is a language with reference semantics (with the exception of primitive types), and C++ a language with value semantics that allows reference semantics through references and pointers.

Syntax that looks similar in both language has complete different meanings, when in Java you create a reference (Test2 x = new Test2();) the equivalent construct in C++ would be using a pointer (Test2 *x = new Test2();).

A key difference is that it is simple to provide reference semantics on top of value semantics through the use of pointers, but it is impossible to provide value semantics on top of (pure) reference semantics. Some of the implications of this statement include not being able to control the layout of objects in Java in memory or the locality of data (for anything other than primitive types and arrays of primitive types), while on the other direction the finer control of objects in C++ allows you to mimic Java objects.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • 2
    Excellent answer! Nobody else gave any reasonable explanation. I don't think many pure Java programmers(if any) can understand this. Knowledge on both C++ and Java is needed for this question. – duleshi Jul 25 '13 at 08:55
  • This of course is an in-depth analysis, but IMHO it fails to address directly the counter-intuition beginners may have: regardless of the semantics, the very same "algorithm" (trying to create a self-referencing loop) is allowed in one language but forbidden in another. A direct and simple answer, as pointed out by @assylias, is that both will eventually fail (c++ at compile time and java at run time). The reason why java compiler does not complaint, is just a matter of choice - unlike the concept of "incomplete types" in c++, the java type system simply chooses to be silent. – wlnirvana Sep 18 '19 at 09:24
14

Re question 2 - if you run this code, you get a StackOverflowException => Yes it creates an inifinite number of objects (well it tries...)

public class Test2 {

    private Test2 subject = new Test2(); //Create Test2 object in Test2

    public static void main(String[] args) throws Exception {
        Test2 t = new Test2();
    }
}
assylias
  • 321,522
  • 82
  • 660
  • 783
4

subject here is a reference to an instance of Test2. If you try to run it, the code will quickly run out of some resource (probably stack space, maybe heap space).

NPE
  • 486,780
  • 108
  • 951
  • 1,012
3

Why does Java permit the above code to be executed but C++ doesn't?

Since 2011, C++ also allows class members to be initalised in their declarations.

However, it wouldn't allow this case: you can only instantiate complete types, and a class type is incomplete within the class definition, so it would have to be initialised in the constructor, or by a call to a function:

class Test;
Test * make_test();

class Test {
    // Test is incomplete, so "new Test" is not possible here
    Test * test = make_test();
};

// Test is complete, so we can instantiate it here
Test * make_test() {return new Test;}

Java doesn't have a concept of incomplete types, so the class can be instantiated anywhere you're allowed to instantiate any class.

Does the code above create infinite objects?

Yes, trying to instantiate such a class would throw your program into a recursive death spiral.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

If you declare subject as being static, you would get an eager initialization version of the Singleton pattern, which will not get you to out of resources.

Dan D.
  • 32,246
  • 5
  • 63
  • 79
  • Hey can you please elaborate a little on how declaring variable as static will not put it into recursive spiral – Varun Aug 01 '17 at 18:32
0

since you can have multiple constructors its allowed. if you only have one constructor this would indeed result in an infinite loop.

public class Test{
    private Test a;

    public Test(String s){
        this.a=new Test();
    }

    public Test(){

    }

}
schippi
  • 1,034
  • 5
  • 15