Why does StackOverflowError occur in the below scenario? - java

public class B {
public static void main(String[] args) {
A a = new A();
}
}
public class A {
A b = new A();
}

Because every A creates an inner field named b of type A. That's infinitely recurisve, because to create a b you must also create an A (which adds another b). Because initializers are copied to the default constructor, your example is equivalent to something like,
public class A {
// A b=new A();
A b;
public A() {
super();
b = new A();
}
}

I dont understand your requirement. Why did you declare instance variable within same class. It will behave like a recursive loop. From the main method it will try to create the object of class A and during that object creation it will try to initialize the variable "a". As a result again it will create another instance of A and so on.

Related

Is there different between this two ways of creating an object

I just have learned java. I'm fiding the different between this both ways of creating an object
public class A {
}
public class B extends A {
}
public static void main(String[] args){
A object = new B();
B object = new B();
}
Lets understand it with the example below.
In class A we added a getMethodofA(). So creating reference variable as A or B does not matter. As A is super class getMethodofA() will be available for both the objects of Type A or Type B
In class B we added a getMethodofB(). So creating reference variable as A or B matters. If you create object with reference variable as A, then only getMethodofA() will be available. While If you create object with reference variable B both the methods will be visible getMethodofA() and getMethodofB()
public class A {
public void getMethodofA(){
System.out.println("I am method A")
}
}
public class B extends A {
public void getMethodofB(){
System.out.println("I am method B")
}
}
public static void main(String[] args){
A objectA = new B();
objectA.getMethodofA();//No error
objectA.getMethodofB();//Compile time error
B objectB = new B();
objectB.getMethodofA();//No error
objectB.getMethodofB();//No error
}

When I call SetA from main and then call show method of class B , Variable value resets to zero

class A
{
Int a =0;
public void SetA(){ //setting a value to 20
a = 20;
}
}
class B
{
public void show(){
SetA obj =new SetA();
System.Out.Println(obj.a)
}
}
First from the main method I called SetA method in class A then call show method in class B but even when I set the values for int a it still returns zero. Someone please explain me why is it happening and how can I fix the issue. How can I access variable a from any onther class with the value that is set in SetA method?
You never invoke the method SetA (although you try to use it instead of the A constructor).
A obj =new A();
obj.SetA();
System.out.println(obj.a);
Demo
The a variable in class A is an instance variable:
In object-oriented programming with classes, an instance variable is a
variable defined in a class (i.e. a member variable), for which each
instantiated object of the class has a separate copy, or instance.
So each instance of class A will have a SEPARATE copy of 'a' that changes individually from all the other class A instances.
In the show() method of class B, you are creating a new, SEPARATE instance of class A that is different than the instance of A that you previously manipulated. The default value of a is zero, which is why that is the only value you'll see.
If you want show() to work with a specific instance of A, then you'd have to pass in that instance as a parameter:
public void show(A someInstanceOfA) {
System.Out.Println(someInstanceOfA.a)
}
Note that we are NOT creating an instance of class A with the new keyword inside of show(). We are simply manipulating or using the local reference passed in via the someInstanceOfA parameter.
Here's a complete example showing how the instance variable a is being manipulated by class B:
public class A
{
private int a=0;
public void setA(int value) {
a = value;
}
public int getA() {
return a;
}
}
public class B
{
public void show(A someInstanceOfA) {
System.out.println("B.show(): a = " + someInstanceOfA.getA());
someInstanceOfA.setA(10); // this will modify the instance of A and be reflected back in main()
}
}
public class Driver
{
public static void main(String[] args) {
A instanceA = new A();
instanceA.setA(5);
System.out.println("Before: a = " + instanceA.getA());
B instanceB = new B();
instanceB.show(instanceA);
System.out.println("After: a = " + instanceA.getA());
}
}
Output:
Before: a = 5
B.show(): a = 5
After: a = 10

(Java) Difference ways of instantiating subclasses

I have these two classes:
public class A {}
public class B extends A {}
In the main class, I would declare:
A a = new B();
B b = new B();
What is the difference between a and b ? Is this what we called a subtyping in java?
The difference between a and b is that with a you can only use the public API that the A class provides even though its really a B type object, but with b, you can use both the A's public API as well as B's public API.
For example:
Suppose A and B are defined as follows:
// A.java
public class A
{
public void x()
{
z("X");
}
public void y()
{
z("Y");
}
protected void z(String message)
{
System.out.println(message);
}
}
// B.java
public class B extends A
{
public void a()
{
z("A");
}
public void b()
{
z("B");
}
}
And here's a demo:
// Demo.java
public class Demo
{
public static void main(String[] args)
{
A a = new B();
B b = new B();
// Can only call A's public methods
a.x();
a.y();
// a.a(); Can't use
// a.b(); Can't use
// Can call all public methods
b.a();
b.b();
b.x();
b.y();
}
}
Yes, there is difference between them. Accssibility of methods are different depends on what kind of reference you use.
A a = new B();
B b = new B();
a is a reference of Class A and b is a reference of class B. super class always can be used to point subclass object.
reference a able to access only super class method and properties
reference b able to access super class and it's own method and properties
one important thing is, ability of accessibility of function and properties will decided at runtime.
In below two cases
A a = new B();
a is an instantiation of B and of type A.
whereas in
B a = new B();
a is an instantiation of B and of type B.
The important thing to note here is that (in the first case) if you call a.someMethod(), the method of B will be called, not the method of A (this is called dynamic binding, as opposed to static binding).
This is basic inheritance. In the B b = ... case you can access all methods and variables provided from A and B but in the A case you can only use the methods and variables in the A case.
B gets typecasted into A when it is created, but that information is not required by the compiler.
public class A {
int x;
}
public class B extends A {
int y;
}
A a = new B();
B b = new B();
int c = a.x; //works
int c = a.y; //doesn't work
int c = b.y; //works
int c = b.x; //works
Remember, that you can always cast an object "downwards" in the inheritance chain. But you should not cast a object upwards because the variables for the subclass might be used even though they dont exist, for exmaple B b = new A(); So b.y is dangerous since the B object doesn't have an y variable defined.

Initializing class

This is the snippet of Java code.
class A{
public A() { }
public A(int i) { System.out.println(i ); }
}
class B{
static A s1 = new A(1);
A a = new A(2);
public static void main(String[] args){
B b = new B();
A a = new A(3);
}
static A s2 = new A(4);
}
The execution order is the following: 1,4,2,3 because the initialization of class performed in this way.
But what if you remove the B b = new B(); object creation, does that mean that the class will not be initialized in the above order?
Best regards
If you remove B b = new B(), then your reference (A a) declared as instance variable will not be initialized with the instance new A(2)
Only static variables are loaded and initialized at the time of class loading. Instance variable are initialized only when you instantiate your class.
Reason is: -
A a = new A(2);
Your above code is converted to: -
A a;
public B() {
super();
a = new A(2);
}
by the compiler. Where B() is the default constructor provided by compiler, since you have not provided your own. If you have declared your own constructor, then the initialization is added to each of your constructor.
So, if you don't instantiate your B class, A a will not be initalized and hence the constructor A(int i) will not be invoked.
if you remove B b = new B() from your main , only 1,4,3 will be printed.
in your class B only the objects marked static will be initialized as they dont require an instance of a class to initialize them. for your class B to invoke.
A a = new A(2);
you need to create an instance of that class, like you are doing in your code currently. if you remove it A a= new A(2) will not be invoke thus, the output would be 1,4,3

Private class in a Vector used publicly

In Java, what happens when you reference a private class in a Vector from outside the class?
Example:
public class A {
private class B {}
public Vector<B> vector = new Vector<B>();
public A() {
vector.add(new B());
}
}
public class C {
public C() {
A a = new A();
a.vector.get(0); // <- What does this return?
}
}
You can try this code:
public static void main(String[] args) {
A a = new A();
Object o = a.vector.get(0); // <- What does this return?
System.out.println(o.getClass());
}
The class is A$B, so it knows that B is an inner class of A.
But you cannot access any of the members of B. For example, if you change class A to this:
public class A {
private class B {
public int x;
}
public Vector<B> vector = new Vector<B>();
public A() {
vector.add(new B());
vector.get(0).x = 10;
}
}
You still won't be able to do this:
public static void main(String[] args) {
A a = new A();
System.out.println(a.vector.get(0).x); // this won't compile
}
It will say the type A.B is not visible.
It returns the reference to an Object of type A$B.
You will be able to assign it to an Object reference, e.g.
Object o = a.vector.get( 0 );
You can even use reflection to investigate properties of o.
Just a general reminder, please use java.util.ArrayList instead of Vector.
It will return an object of type A.B However you cannot do anything with it really because you will not be able to assign it to a variable or call any methods on it. If you do:
System.out.println(a.vector.get(0));
you will get something like:
A$B#42e816

Categories

Resources