public class FooClass {
BarClass bar = null;
int a = 0;
int b = 1;
int c = 2;
public FooClass(BarClass bar) {
this.bar = bar;
bar.setFoo(this);
}
}
public class BarClass {
FooClass foo = null;
public BarClass(){}
public void setFoo(FooClass foo) {
this.foo = foo;
}
}
elsewhere...
BarClass theBar = new BarClass();
FooClass theFoo = new FooClass(theBar);
theFoo.a //should be 0
theBar.foo.a = 234; //I change the variable through theBar. Imagine all the variables are private and there are getters/setters.
theFoo.a //should be 234 <-----
How can I pass an object to another class, make a change, and have that change appear in the original instance of the first object?
or
How can I make a cycle where one change to a class is reflected in the other class?
That's already exactly how objects work in Java. Your code already does what you want it to.
When you pass theBar to the FooClass constructor, that's passing the value of theBar, which is a reference to a BarClass object. (theBar itself is passed by value - if you wrote foo = new FooClass(); in the BarClass constructor, that wouldn't change which object theBar referred to. Java is strictly pass-by-value, it's just that the values are often references.)
When you change the value within that object using theBar.foo.a, then looking at the value of a again using theFoo.a will see the updated value.
Basically, Java doesn't copy objects unless you really ask it to.
Related
Sometimes in a constructor, no statement is given. What does that indicate? For example if i create a class CIRCLE, then inside the class i write CIRCLE() {}, that is nothing is written inside. Can anyone explain it?
If your question is "why would anyone write such a constructor", then the answer is that the no-args default constructor only exists if no other constructor is specified.
Consider the following class.
class Foo {
int x;
}
As written, someone could write the following code to construct Foo.
Foo foo = new Foo();
However, now suppose I added a constructor which takes arguments.
class Foo {
int x;
public Foo(int x) {
this.x = x;
}
}
Now, suddenly, Foo foo = new Foo(); no longer works. To restore it, I must add the empty constructor again.
class Foo {
int x;
public Foo(int x) {
this.x = x;
}
public Foo() { }
}
Now, What if there are no other constructors that take arguments?
In that case, it is generally as the other answers suggest, to restrict access to constructing the class.
In the following definition of Foo, nobody is allowed to construct Foo. Perhaps Foo is meant only as a static class.
class Foo {
int x;
private Foo() { }
}
In the protected case, only subclasses can construct Foo.
class Foo {
int x;
protected Foo() { }
}
If there is no code in the constructor, chances are, it was declared to change the access to the constructor. By default, constructors are public. If you wanted to make it private, protected or package-private, you must explicitly declare it and manually change the modifier.
class Example {
public static void main(String[] args) {
new Demo(); //this is currently allowed
}
}
class Demo {
}
In order to prevent the creation of a Demo object within Example, we could declare Demo's constructor amd make it private:
class Demo {
private Demo() { }
}
Another reason could be that the class has a constructor that requires parameters. If so, you must explicitly declare the no-arg constructor to be able to use it.
If nothing is written, then when a new Object of that type is created, nothing 'extra' is done, whereas if in the constructor has code in, it does something.
For example, the following consructor for a class called 'Bank' assigns the argument 'name' to the field 'bankName', then instantiates a Terminal and 2 bank accounts:
private static final int INITIAL_BALANCE = 200;
public Bank( String name )
{
bankName = name;
atm = new Terminal();
account1 = new BankAccount( INITIAL_BALANCE );
account2 = new BankAccount( INITIAL_BALANCE );
}
It's a default constructor. For instance if you go:
Circle circle = new Circle();
You are then calling the default constructor. When you go ... Circle() that is a call to the default constructor, the one with no parameters.
The point of this is just to 'construct' an object or instantiate a class (instantiate just means create an object which is an instance of the class) with no additional information i.e. parameters.
This would generally be used to initialize fields to their default values, like so:
public Circle() {
this.x = 0;
this.y = 0;
}
I want to set the value of the next array object whenever an object is created in my main function.
This is the object
public class MyObject{
private int objCount = 0;
private int i = 0;
public class Property{..}
public Property propertyArray[] = new Property[12];
}
Main function creates an empty object and adds properties to the property array.
The object needs to keep different number of properties.
MyObject foo = new MyObject();
foo.add("ID", 2);
foo.add("MIE",132);
MyObject bar = new MyObject();
bar.add("REV", 22);
There is also an array of the object,
public MyObject[] ObjectArray = new MyObject[5];
I want to call a method that increases the object array index when a new object is created
Yes, Java makes a call when a new object is created, except it's not calling a method, it is calling a constructor. Constructors are declared like methods with no result type, and the name matching the name of the type, i.e. like this:
public class MyObject {
private int objCount = 0;
private int i = 0;
public class Property{..}
public Property propertyArray[] = new Property[12];
// This is the constructor
public MyObject() {
... // <<== Do stuff here
}
}
If you would like to add items to an array inside the MyObject class constructor, the array needs to be static: although constructors can access instance variables, each constructor gets a brand-new set of instance variables with which to work.
I have an object, obj, of type MyObject, that I declare an instance of.
MyObject obj;
However, I don't initialize it. MyObject's Class looks something like:
public class MyObject {
public String i;
public String j;
public MyObject(String i) {
i = this.i;
}
}
So now, I want to set the value of j. So I say:
obj.j = "Hello";
Can I do this without having initialized obj? i.e. without saying:
obj = new MyObject("My i");
Will this object be null if I were to check the value of it, if I don't initialize it, or is setting a field within it enough to make it not null?
Thanks!
No, you cannot do that. You will have to create a new instance of MyObject if you want to access its fields.
Unless you make the fields static, ofcourse.
Do note that having your fields public violates encapsulation. You should make them private (or protected, if it's appropriate) and use getters and setters to provide access.
Sidenote:
public MyObject(String i) {
i = this.i;
}
This will not do what you want.
You have to assign the parameter i to the field variable i, not the other way around.
public MyObject(String i) {
this.i = i;
}
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 9 years ago.
Suppose I have a class and constructor called TestClass.
public class TestClass {
Foo foo;
public TestClass(Foo foo) {
this.foo = foo;
}
}
Here, the constructor accepts an object which is an instance of class Foo. Suppose my static void main(String[] args) does the following, completely separate from any TestClass;
(1) Instantiate foo
(2) Pass instance foo to TestClass constructor
(3) Change the internal state of foo
After step (3), will the foo within my instance of TestClass also have its state changed?
It is not passed by reference. Rather, it is passed by value of the reference, which is a subtle but important distinction.
After you mutate foo in the rest of your main() method, the foo field will also exhibit these mutations, as you state, since both variables point to the same instance. However, if you reassign foo to something new, the foo field will not be changed. This would not be true if foo were truly passed by reference. In short, everything is passed by value in Java; it just so happens that objects are dealt with by reference, and so the values of these references are passed.
I'll try to illustrate this with an example. Consider the following class:
class A {
public int n;
public A(int n) {
this.n = n;
}
}
and the following method:
public static void mutate(A a) {
a.n = 42;
}
Now we can have something like this:
A a = new A(0);
A.mutate(a);
System.out.println(a.n);
42
We can see that the state of a was changed in mutate(). Now let's modify the static method:
public static void mutate(A a) {
a = new A(42);
}
and try again:
A a = new A(0);
A.mutate(a);
System.out.println(a.n);
0
As you can see, the state of a is unchanged. If the reference had been passed to the function, we would expect the effect of the reassignment to be evident beyond the scope of the method. Nevertheless, some reference was in fact passed, since mutating the argument caused changes outside of the method as well.
Yes, because you are assigning same object to another reference of Foo class, i.e. object is same, but being referred by two reference.
After step (3), will the foo within my instance of TestClass also have
its state changed?
Yes.
You might like to take a read through this
Updated...
Now, assuming you pass the constructor a primitive value...
public class TestClass {
int foo;
public TestClass(int foo) {
this.foo = foo;
}
public String toString() {
return "TestClass: " + foo;
}
}
public static void main(String args[]) {
int myFoo = 1;
TestClass test = new TestClass(myFoo);
myFoo += 2;
System.out.println("myFoo = " + myFoo);
System.out.println("yourFoo = " + test);
}
This will output...
myFoo = 3
yourFoo = 1
Which demonstrates the fact that changing the value of a primitive does not change the value maintained by the constructor/method.
Equally, if you change the object reference after you pass it
public class TestClass {
Foo foo;
public TestClass(Foo foo) {
this.foo = foo;
}
public Foo getFoo() {
return foo;
}
}
public static void main(String args[]) {
Foo myFoo = new Foo();
TestClass test = new TestClass(myFoo);
myFoo = new Foo();
System.out.println("myFoo == yourFoo = " + myFoo.equals(test.getFoo()));
}
Will output
myFoo == yourFoo = false
As the object references are not the same.
I've been looking for the answer to this problem all day.
I have a value class that holds a variety of values as long as the program is running.
I create a new Value object in class A, and store an int value.
Class A also has a printMoney() method.
public class A {
Value value = new Value();
value.setMoney(100);
public void printMoney {
System.out.println(value.getMoney);
}
In class B, I want to be able to call printMoney() from class A, so logically I do the following:
public class B {
A a = new A();
a.printMoney();
}
This does, however, return '0' as a value instead of '100'.
I understand that by creating an A object, I automatically create a new value object, which has its default money value. So, basically my question is; how do I solve this?
Make the object static. static Value value = new Value();
static variables are shared across all the objects
So the change made in static variable will be reflected for all the objects of class.
if you want to get that value in A you have to assign the value in A construtor, like
public class A {
Value value = new Value();
public A() {
this.value.setMoney(100);
}
otherwise, you can make the value static
you should receive the instance that creates the object B and save it then you would be able to call it
like so:
public class A {
B b = new B(this);
}
public class B {
A a;
public B(A a) {
this.a = a;
}
private someMethod () {
a.printMoney();
}
}