java.lang.StackOverflowError at line A a=new B() - java

at line A a=new B() i am getting error
abstract class A{
}
class B extends A{
A a=new B();
}
public class Test {
public static void main(String[] args) {
B ab=new B();
System.out.println(ab.a);
}
}
I don't know why am i getting that error

You are recursively creating instances of B.
class B extends A{
A a=new B(); // will get called infinitely. So, you get StackOverFlowError
}

A StackOverflowError means that you have too many function calls to fit their data on the stack. Usually it's an indication that you have infinite recursion going on, as you do in this case.
When you are creating the object B in class Test, the class B is creating another object B, over and over.
class B extends A{
A a=new B(); // problem here
}

The fact that you call B's constructor inside of B's declaration is a case of infinite recursion. There's no way for that to work.
You'd instead have to lazy-load the instance on request:
class B extends A {
private A a;
public A getA() {
if(a == null) {
a = new B();
}
return a;
}
}
Obviously this code isn't thread-safe, but it'll at least get you started.

class B extends A{
A a=new B();
}
At line A a=new B(); , again the default constructor of class B is invoked. This keeps happening, and the stack gets full due to frames of B's constructor calls.

In code
class B extends A{
A a=new B();
}
you decided that each instance of B needs to have its own field which will hold other instance of B.
So each time you call new B(), another instance of B needs to be created, but this another instance needs to also have its own another instance of B, and so on.
You can visualize it this way
new B()
|(requires)
+-- A a = new B();
|(requires)
+-- A a = new B();
|(requires)
+-- A a = new B();
|(requires)
+-- ... and so on until stack will overflow.

Related

call class with in a class from other java program

If there are two classes in a java program and we have another java program how can we use the function of 2nd class of first java program to 2nd java program e.g
One java program
Public class A
{
Public class B
{
void a();
void b();
}
}
Second java program
Public class C
{
i want to call void a() and void b() here
}
You can do it by inheritance.
public class C extends B {
public static void main(String args[]){
C foo = new C();
foo.a();
foo.b();
}
}
In C, you would need to create an instance of B. Let's call this instance bTest. You could then call these methods like this:
B bTest = new B();
bTest.a();
bTest.b();
Now, if you made a() and b() static methods, you would call them using the name of the class they are in rather than using an instance of it, as such:
B.a();
B.b();
Keep in mind that you will have to import B if it is not in the same package as C.
Since your inner class is not static one you have to create an object of A first and then create object of B.
A a = new A();
A.B b = a.new B();
b.a();
b.b();

Is a class that creates an instance of another its parent?

If class A creates an instance of class B, then in class B can I run a method from class A? sorry if the question is poorly worded, I don't know how else I could say it.
In the below code, Class A creates an instance of Class B and you can call Class A's method from Class B's method.
class A {
public void getA() {
System.out.println("In A");
}
public static void main(String[] args) {
B b = new B();
b.getB();
}
}
class B {
public void getB() {
System.out.println("In B");
A a = new A();
a.getA();
}
}
Output:
In B
In A
In class B you can call methods of class A only if A's methods are visible to B. It doesn't matter who created an instance of B.
This tutorial might help: http://www.tutorialspoint.com/java/java_access_modifiers.htm
So you can call it if the method is one of the following:
public
protected (and B is a subclass of A or B is in the same package as A)
no modifier (and B is in the same package as A)

Assign on declaration or assign in the constrctor?

is there a diffrence between this :
public class A {
B b;
A() {
b=new B();
}
}
and this :
public class A {
B b=new B();
A() {
}
}
if there is, what is it? and what is better practice?
if there is no, whats recommanded?
As far as i know there is no difference as long as you only have one constructor. If you have more than one constructor you will need to make sure it's assigned in all constructors. For that reason i would recommend the second approach.
The constructor runs after the instance variables are initialized, so there is a difference. It doesn't matter in a small example, but it can matter with more complex code. (Note, the order of the code doesn't matter. If the initialization is in the constructor, it runs second.)
The second approach is more convenient, so I tend to start with it. The first approach can be more useful though (for Inversion of Control and Polymorphism), so it often gets used in "real" code.
class B {
B() {
System.out.println("B constructor");
}
}
public class A {
B b=new B();
A() {
System.out.println("A constructor");
}
public static void main(String[] args) {
new A();
}
}
Output:
B constructor
A constructor
....
class B {
B() {
System.out.println("B constructor");
}
}
public class A {
B b;
A() {
System.out.println("A constructor");
b=new B();
}
public static void main(String[] args) {
new A();
}
}
Output:
A constructor
B constructor
Big Difference between them.
In first option Class B only instantiate when constructor without parameter is called. If you put and call any parametrized constructor Class B will not instantiate.
But in case of second option Class B will always instantiate regardless of any constructor call.

what gets typecasted when 2 classes are casted? is it the object?

I have 3 classes A,B and c as follows
A.java
class A
{
protected A(){
System.out.println("A");
}
void show()
{
System.out.println("showA");
}
}
B.java
class B extends A
{
B(){
System.out.println("B");
}
void show()
{
System.out.println("showB");
}
}
C.java
class C extends B
{
C(){
System.out.println("C");
}
void show()
{
System.out.println("showC");
}
public static void main(String... args)
{
A a= (B)new C();
a.show();
}
}
When executed gives the output
D:\java\rmi\Hello>javac C.java
D:\java\rmi\Hello>java C
A
B
C
showC
I know a superclass cannot be casted to a subclass.But in the output why is it executing the C class method (show) when there is a cast to the super class B?
A a= (B)new C();
And if this is right then what is it that is getting casted to B?
I mean here new C() would call the C constructor and hence the respective outputs but
what is the difference between new C().show(); and (B)new C().show(); what is getting casted here?
Casting an object does not change its type.
(B) new C();
will still create an object of type C, no matter what you cast it to. But if you only create a B it will of course only ever be a B which is why C’s constructor is not called when you execute
(C) new B();
The error "B cannot be cast to C at C.main" means that the superclass B is casted by C which is a subclass.(Just read it again and again and you will understand it..)
You can cast in lower element in the hierarchy with the upper element but not vice-verse..
Hope you got it :)
Class B does not extend C, so it has no knowledge of it and connot be casted to C. With java, you can down cast but not upcast.
OK:
A a= (B)new C();
-> C inherits from B, so cast is possible
Not OK
A a= (C)new B();
-> B does not inherit from C, so it cannot be cast to it
see also: Downcasting in Java
Edit:
Please consider to edit your question, as most users tend to correct an error first. (Remove the error and break it down to your original question)
"what is the difference between new C().show(); and (B)new C().show();"
This is called 'polymorphism'. there is no difference between the two calls, as java will always execute the method of the lowest level of the hierarchy.
For example:
class Bird{
public void fly(){
System.out.println("I am flying");
}}
class Duck extends Bird{
public void fly(){
System.out.println("I can not fly");
}}
class Test{
public static void main(String[] args){
Bird[] birds = {new Bird(), new Duck()};
for (Bird b: birds){
b.fly();
}
}
This would output:
I am flying
I cannot fly
When you are creating an object of a class, its superclass objects are created first.
So when you says
A a = (B)new C();
While creating object of C, its superclass objects are first created. So the object of C can be casted to B.
But in the later case while creating the object of B, it would not possible.
Always remember that a subclass object can be casted into superclass, where as a superclass object can not be casted to its subclass, which is done by you in the second case, so it gives you compilation error.

related to abstract class reference holding object of its derived class

class A is abstract and class B extends class A
now class A reference can hold object of class B,that is
A aObj = new B();
and assume class B has some extra methods....
like
class A
{
public show();
}
class B extends A
{
public show(){}
public method1(){}
private method2(){}
}
now tell me what things variable aObj can access from class B
can it access everything?
aObj only sees the public show() method. If you cast aObj to B, you can then access public method1(). public method2() is only accessible to the implementation of B.
For reference and completeness, here's a list of the possibilities:
A aObj = new B();
aObj.show(); // Works
aObj.method1(); // Error
aObj.method2(); // Error
And with casting to B:
B bObj = (B)aObj; bObj
bObj.show(); // Works
bObj.method1(); // Works
bObj.method2(); // Works inside bObj, but error otherwise
aObj can only use show() as the compiler thinks aObj is of type A, and the only known method of A is show().
If you know that you actually have a B you can cast that object to a B:
if (aObj instanceof B.class) {
B bObj = (B) aObj;
bObj.method1(); //OK
} else {
log.debug("This is an A, but not a B");
}
aObj.show();

Categories