Suppose we have a class like:
public class test {
int a=1;
static int b=1;
public int getA()
{
return a;
}
public void incrementA()
{
a++;
}
public void incrementB()
{
b++;
}
public int getB()
{
return b;
}
}
and I have a class with main method like this
public class testmain {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
test t= new test();
t.incrementA();
test t1= new test();
test t2= new test();
t2.incrementB();
test t3 = new test();
test t4= new test();
t4.incrementB();
System.out.println("t= "+t.getA());
System.out.println("t1= "+t1.getA());
System.out.println("t4= "+t4.getB());
System.out.println("t3= "+t3.getB());
System.out.println("t2= "+t2.getB());
}
}
I need the explanation about why t and t1 have different value of a, and all t2, t3, t4 have the same value of b. I know that I have declared b as static and all objects access the same address of that variable b. Why it is not causing any problem for a variable when each object it has its own a, now my question is since all the objects look to the same location in memory then why is a different value of each object?
Every object has its own exemplar of a. So there are as many a's as objects
Class (static) variable value will be accessible multiple instances of the class, In this case t...t4.
When you change 'b' using t.b (or) t4.b (or) test.b (or) using any methods of t..t4--> same 'b' value will be updated, becuase only one copy of 'b' exists across these.
Instance variable is specific to that instance. 'a' exists a copy for each instance t...t4.
Read this link for more details.
Related
class C {
public static void main(String[] args){
B test = new B(1);
}
}
abstract class A {
int i = 1;
abstract void test();
public A(){
System.out.println("before test()");
test();
System.out.println("after test");
}
}
class B extends A {
int i = 1;
#Override
void test(){
System.out.println("test()" + i);
}
public B(int i) {
System.out.println("before test()");
test();
System.out.println("after test");
}
}
When I run this code, the output is
before test()
test()0
after test
before test()
test()1
after test
I know the first set of output results comes from the construction method of A, and I don't know
why the variable i is 0 for the first time, but in second time is right.
You are creating an instance of B using the constructor B(int i).
That constructor starts by executing the super class constructor public A(). This constructor calls test(), which is overridden in the B class and prints the i variable of class B.
That variable is not yet initialized, since the constructor of the super class is executed before the instance variables of B are initialized. Therefore, it still contains the default value 0.
After the constructor public A() is done, B's instance variables are initialized (so i is initialized to 1), and B's constructor body is executed. It calls test(), which now prints 1.
This question already has answers here:
calling a function in a class's "owner" class
(8 answers)
Is there a way to access the variables of the calling class in a method?
(3 answers)
Closed 3 years ago.
An instance a of class A has an instance b of class B.
How can b access a variable of a?
class A {
boolean flag;
B b;
public static void main(String[] args) {
A a = new A();
}
public A() {
b = new B();
b.doSomething();
chageFlag();
b.doSomething();
}
void changeFlag() {
// do something with flag
}
// other stuff
}
class B {
void doSomething() {
// here I need to access a from the instance owning b.
boolean aFlag = ?? // how to access a.flag ??
}
}
You will not be able to access a variable of A in this instance because A and B have no parent/ child or outer/inner class relationship here.
The way to do this is to pass the instance of A to B, such as,
B b = new B(this);
For this you need to adjust the constructor to take in A as a parameter.
As your code is, b has no way of reaching a; simply because it does not have a reference to it.
If the two classes are so related that you need b to know about a, then you can make B an inner class in A:
class A {
boolean flag;
B b;
public static void main(String[] args) {
A a = new A();
}
public A() {
b = this.new B();
b.doSomething();
changeFlag();
b.doSomething();
}
void changeFlag() {
}
class B {
void doSomething() {
boolean aFlag = flag;
}
}
}
B.doSomething() is able to read flag from the enclosing class because B is an inner class.
Be aware that this solution is not appropriate in all situations, it makes the coupling between the two classes even tighter.
Can someone please elaborate me in detail the following scenario, it would be more convenient if the explanation includes the memory allocation and its reference for the three cases :
How is the flow executed in the three cases ?
Why the flow differ in the three cases ?
Though there is a circular dependency between the two classes why the case 1 alone gets executed where as the remaining cases were failed ?
CASE ONE
namespace CircularDependency_1
{
class Program
{
static void Main(string[] args)
{
A a = new A();
Console.WriteLine("executed");
Console.ReadLine();
}
}
public class B
{
public static A a = new A();
public B()
{
Console.WriteLine("Creating B");
}
}
public class A
{
public static B b = new B();
public A()
{
Console.WriteLine("Creating A");
}
}
}
OUTPUT
Creating A
Creating B
Creating A
executed
CASE TWO
namespace CircularDependency_1
{
class Program
{
static void Main(string[] args)
{
A a = new A();
Console.WriteLine("executed");
Console.ReadLine();
}
}
public class B
{
public static A a;
public B()
{
a = new A();
Console.WriteLine("Creating B");
}
}
public class A
{
public static B b;
public A()
{
b = new B();
Console.WriteLine("Creating A");
}
}
}
OUTPUT
Process is terminated due to StackOverflowException.
CASE THREE
namespace CircularDependency_1
{
class Program
{
static void Main(string[] args)
{
A a = new A();
Console.WriteLine("executed");
Console.ReadLine();
}
}
public class B
{
public A a;
public B()
{
a = new A();
Console.WriteLine("Creating B");
}
}
public class A
{
public B b;
public A()
{
b = new B();
Console.WriteLine("Creating A");
}
}
}
OUTPUT
Process is terminated due to StackOverflowException.
#Versatile, you are close, but not right. The reason why the first case executes and two other cases fail, is not just because the objects are created inside the constructor or inside the class (outside of the constructor). To prove this, try making the a and b fields not static in the B and A classes (Case one), respectively; and you will see that it will fail, even though the objects are created outside of the constructor.
Case 2 and 3 fail because of the reasons explained by #Versatile.
Case 1 executes because of static members.
Let's examine the flow:
In the Main method the line A a = new A() begins creating the a object. In this process, an object of class B will be created because of the line public static B b = new B() - this very line will start creating another object of the class A because of the line public static A a = new A() in the body of class B. Now, here comes the magic (that doesn't fire a circular dependency). This line, public static A a = new A() will start creating another object of class A, while creating this object it won't create another object of class B because it is a static member of A, and it was already created. As we know, static members of a class are shared among all instances of the class. Therefore, it won't trigger the creation of another object of class B. In total, we end up with three instances of the classes in the order : A, B, A.
UPDATE
It is interesting to observe, in the first case, what happens if we initialize the static member inside the constructor. Even though, the A and B classes declare static members, the execution will fail due to circular dependency. This is because the static members are not initialized before the constructor is executed.
1.How is the flow executed in the three cases ?
First the static void Main() gets called and then the constructor of object A is called because of code line A a = new A();
2.Why the flow differ in the three cases ?
3.Though there is a circular dependency between the two classes why the case 1 alone gets executed where as the remaining cases were failed ?
Both the above scenarios are observed for the same reason. If you look closely, you assign memory as follows.
Case1 in the class and not the constructor. i.e.
public class A
{
public static B b = new B();
}
Moreover the object is static so it will be created only once and as this is created once the memory which is assigned in the same line gets executed only once.
Case 2 and Case 3: Memory to Objects A and B is assigned in the constructor i.e. in constructor of A the memory is assigned to B and in constructor of B memory is assigned to A, which results in calling the respective class constructors again and again until it throws an exception.
I have just begun learning Java and I am trying to test stuff by myself. Below is the code where I am getting an error. I am trying to call the local variable in class B in class Demo using object of class B.
public class Demo {
public static void main(String args[])
{
B obj=new B();
System.out.println("printing that variable "+obj.a);
}
}
class B{
public void test()
{
int a=10;
}
}
Output:
Exception in thread "main" java.lang.Error: Unresolved compilation
problem: a cannot be resolved or is not a field at
Demo.main(Demo.java:7)
You can always call, but that needs to be in scope and when the current context have access to.
System.out.println("printing that variable "+obj.a);
You cannot do that since the variable a is local to the method test() and scope is restricted to that method only.
To access the way you want now, make it as a instance member.
class B{
int a; // instance member now
public void test()
{
a=10;
}
}
Now note that unless you call the method test() the default value is 0 only. Hence you might want to change your code as
public static void main(String args[])
{
B obj=new B();
obj.test();
System.out.println("printing that variable "+obj.a);
}
and if you don't want to call a method at all want to access a directly, you can do
public class Demo {
public static void main(String args[])
{
B obj=new B();
System.out.println("printing that variable "+obj.a);
}
}
class B{
public int a= 10;
}
Imp note :Always resolve all the compile errors before running your program :)
Because in
class B {
public void test() {
int a = 10;
}
}
a is local variable of test method. If what you are trying to do would be possible, what value should be used in scenario like
class B {
public void test1() {
int a = 10;
}
public void test2() {
int a = 20;
}
}
Should a come from test1 or from test2? For compiler this two methods are equally correct so it can't decide for you, which would cause the problem. Also lets not forget that method can have few variables with same name as long as they are in different scope, that is why we can have few for(int i...) methods (so from which scope you would want to use i).
Generally . operator is used to get access to member of class, not variable from method. So via object.member you may access to object.method() or object.field. If your class would look like
class B{
public int x;
public void test1() {
int a = 10;
}
}
you could use object.b since b is class B field.
Anyway if you want to get access to value of variable created and used only in method test, you could change this method to return this value. In other words you could rewrite it like
public int test1() {
int a = 10;
//... you can do something with a
return a;
}
Now in main method in Demo class you could use int result = obj.test();
Why does below code prints "1" ?
class A {
int x = 1;
}
class B extends A {
int x = 2;
}
class Base {
A getObject() {
System.out.println("Base");
return new B();
}
}
public class CovariantReturn extends Base {
B getObject() {
System.out.println("CovariantReturn");
return new B();
}
/**
* #param args
*/
public static void main(String[] args) {
Base test = new CovariantReturn();
System.out.println(test.getObject() instanceof B);
System.out.println(test.getObject().x);
}
}
Because you are referring to fields, which are not affected by polymorphism. If you instead used getX(), it would've returned 2.
What you are asking is, the value of field x defined in class A (because Base.getObject() returns A). Even though CovariantReturn overrides the method to return B, you are not referring to your object as CovariantReturn.
To expand a bit on how fields are not affected by polymorphism - field access is realized at compile time, so whatever the compiler sees, that's what's accessed. In your case the method defines to return A and so A.x is accessed. On the other hands methods are invoked based on the runtime type. So even if you define to return A but return an instance of B, the method you invoke will be invoked on B.
#kris979 Though you are returning B, i think what makes the difference is that the return type is of A. Hence value of x in A i.e. 1 is printed.
As Bozho pointed out - instance variable are never affected by polymorphism. Let me give you a quick small example.
class Base {
int i = 1;
void method() {
System.out.println("in base");
}
}
class Sub extends Base {
int i = 2;
void method() {
System.out.println("in sub");
}
}
public class Test {
public static void main(String[] args) {
Base obj = new Sub();
obj.method();
System.out.println(obj.i);
}
}
This code will print - in sub and 1