Java: class inheriting itself

I know this is pointless: I just find it funny, and I want to learn more about the mechanism of what happens when you create a class that inherits itself, which leads to failure. Surprisingly, Java allows you to start such a construction.

I just guess, but does the JVM put itself in an infinite loop trying to resolve the class before it starts, or does it actually endlessly run multiple instances of the class?

I should have been more specific; I use the inner class to output from the surrounding class.

public class Outside { private int outsideValue; public class Inside extends Outside { private int insideValue; public Inside(int val) { insideValue = val; } } public Outside() { Inside o = new Inside(0); } } public class Main { public static void main(String args[]) { Outside o = new Outside(); } } 
+8
java inheritance oop
source share
8 answers

Remember that since Inside extends Outside , it has an implicit call to super() , which is the Outside constructor (which, in turn, calls the Inside constructor), and therefore it goes around.

The code you submitted is conceptually no different from the following program :

 class A { B b = new B(); } class B extends A { } public class Test { public static void main(String[] args) { new A(); // Create an A... // ... which creates a B // ... which extends A thus implicitly creates an A // ... which creates a B // ... } } 
+8
source share

In its final form, this problem has nothing to do with circular inheritance and inner classes. This is just infinite recursion caused by an unconnected recursive constructor call. The same effect can be shown by the following simple example:

 public class A { public A() { new A(); } } 

Please note that this code is completely correct, since Java does not impose any restrictions on recursive calls.

In your case, this is a little more complicated due to inheritance, but if you remember that the subclass constructor implicitly calls the superclass constructor, it should be clear that these calls form infinite recursion.

+2
source share

Try in an IDE such as eclipse, this will not allow you to do this. those. gives such an error.

Loop detected: type Test cannot extend / implement itself or one of its own member types

+1
source share

Extending itself generates a cyclic inheritance error (which java does not allow). Your sample code is compiled and valid.


Due to the insistence of Vladimir Ivanov, I will correct my editing.

Your code throws a StackOverflowError because of the following.

 Inside o = new Inside(0); 

Since Inside extends Outside , Inside first calls the super() method implicitly (since you didn’t call it yourself). The Outside() constructor initializes Inside o , and the loop starts again until the stack is full and full (there are too many Inside and Outside inside the heap heap).

I hope this helps Vladimir Ivanov especially.

+1
source share

The java compiler is not going to enter an infinite loop when trying to introduce a loop chain of inheritance. In the end, each inheritance chain is a finite finite graph (and, with computational account, with a very small number of nodes and edges). More precisely, the inheritance graph from subclass A to the (possible) superclass Z should be a string (and not a different path, though), and the compiler can easily determine whether it is a string or not.

It does not take a long time for the program to determine if such a small graph is cyclic or not, or if it is a string or not, which the compiler does. Thus, the compiler does not go into an infinite loop, and the JVM never ends from the stack space, since 1) no compiler works on the JVM, nor 2) the JVM does not start (because it does not compile, and the compiler never calls under such conditions JVM anyway.)

I don’t know any language that allows such cyclical inheritance graphs (but I have not done anything except Java for 11 years, so my memory of anything other than Java is soft.) I don’t see, besides, the use of such a design (in modeling or in real life). Perhaps theoretically this is interesting.

change

Ok, I ran your code and really caused a stack overflow. You were right. I need to sit and really study this to understand why the compiler allows such a design.

Nice to find !!!!

+1
source share

The example you provided may become problematic if we change it a little more:

 public class Outside { public class Inside extends Outside { public Inside(int val) { } } private Inside i; public Outside() { i = new Inside(); } } 

But this is not due to the fact that Inside is an Outside inner class; it could happen to separate top-level classes equally.

+1
source share

You can get the answer:

 Class.forName("MyClass"); 

Thus, it is allowed, but not created. This way you can hack if the resolution itself causes a crash.

I think it depends on the JVM you are using.

0
source share

When I try to compile:

 class A extends A { } 

I get:

 $ javac A.java A.java:1: cyclic inheritance involving A class A extends A { ^ 1 error 

So Java doesn't allow you to do such things. For information java version "1.6.0_24"

0
source share

All Articles