Constructors: do Instance variables store separate values for objects? - java

Suppose we initialize the instance variables with some values, and then again initialize them inside a constructor with some other values, so does that mean that variables will hold separate values for objects regardless of what we initialized them to outside the constructor? For example:
class A {
int a = 2;
A(int p) {
a = p;
}
public void Foo(String args[]) {
A obj = new A(5);
}
}
In the above code, do 'a' and 'obj.a' hold seperate values?

In the above code, do 'a' and 'obj.a' hold seperate values?
Yes. obj.a holds the value 5, while a holds the value "there isn't any such variable and there's no meaningful answer to what its value is."
There is no a by itself, only the value of a associated with a particular instance of the class A.

Related

In Java are object attributes passed by reference to other classes

If I have a class like such:
public class First {
int x = 1;
}
and a second class:
class Main {
public static void main(string args[]) {
First someObject = new First();
someObject.x = 2;
}
}
is only someObject.x equal to 2 or would any object of class First being created afterwards be initialized with it's x attribute being equal to 2. If not, how would one change the default value of x for any object being made of class First?
First of all, you need to read about what "pass by reference" really means. (For example, here.) Passing semantics refer to what happens to arguments in a procedure/method/subroutine/function call. In your example, there is no "passing" going on at all when you are assigning to the x field.
So your
In Java are object attributes passed by reference to other classes
is a meaningless and/or irrelevant question. (But the plain answer is that Java does not support "pass by reference". Period.)
As for what I think you are trying to ask, lets start with some facts:
The Field class declares x as an instance field.
Each instance of First has its own "copy" of the x field.
The x field is part of one and only one instance. It is not shared with any other First instance.
This is irrespective of the declared type of x ... modulo that a field whose declared type is a reference type will contain a reference to an object rather than the object itself. (But int is not a reference type.)
The new First() expression creates a new instance of the First class that is distinct from all other (past, present or future) instances of First and returns its reference.
So, in this code:
First f1 = new First();
First f2 = new First();
f1.x = 2;
System.out.println(f2.x); // prints 1.
We have two instances of First that f1 and f2 refer to (point at) distinct First instances. If you change the x field of one instance does not change the x field of the other intance. They are different fields.
However, if you had declared x as static in First, then x is no longer a distinct field for each First instance. It is now a shared by all instances of First.
As an addendum, how would one change the default value of x in the First class such that any new instance made afterwards would have a difference value of x to start?
Firstly int x = 1; in First is not defining a "default" value in the sense that Java uses that term. It is actually an initialization. (A default value is what you see if you DON'T have an initialization.)
If you wanted to implement application specific default value that is common to all instances of First and that can be changed retrospectively, you need to implement it in Java code. Maybe something like this:
public class First {
static int defaultX = 1;
private int x;
private boolean xSet = false;
public int getX() {
return xSet ? x : defaultX;
}
public void setX(int x) {
this.x = x;
this.xSet = true;
}
}
Note that in order to implement the defaulting behavior we want, we have to hide the x field (make it private) and implement the desired behavior in the getter and setter methods.

How actually values get assigned to object reference(actual memory,allocated by new) which are initialized by Constructor?

class box
{
double height,width,depth;
box(double h,double w,double d)
{
height=h;
width=w;
depth=d;
}
}
class boxdemo7
{
public static void main(String args[])
{
double vol1,vol2;
box mybox1=new box(10,12,16);
}
}
In these program in the box class I declared three double type variables, and I initialize those with constructor meaning I set the state of the object which is using the constructor. My Question is height,width,depth got memory allocated for them when declared within box class, so by using constructor they got values 10,12,16 and these values taken by object mybox1. So mybox1's memory location has these values ?or these variables memory has these values and a reference to those are stored to objets referred location ? How memory works while an objects internal state gets the values ?
Primitive types are passed by value, unlike objects. So in this particular case the values 10, 12 and 16 will be assigned to the fields inside your box object. With objects, on the other hand, it will depend on your implementation of the constructor. If you use a simple assignment operator the field will get a reference to the passed object, and changes to the passed object will change the object the field refers to. If you create a new object based on the passed object they will remain independent.
Try this code:
public class Test {
static class sample{
int primitive;
int[] object;
sample(int prim, int[] obj){
primitive = prim;
object = obj;
}
}
public static void main(String... args){
int primram = 0;
int[] objectParameter = new int[1];
sample demonstration = new sample(primram,
objectParameter);
System.out.printf("Old Values: %d, %d%n",
demonstration.primitive,
demonstration.object[0]);
primram++;
objectParameter[0] = primram;
System.out.printf("New Values: %d, %d%n",
demonstration.primitive,
demonstration.object[0]);
objectParameter = new int[1];
System.out.printf("Unchanged Values: %d, %d%n",
demonstration.primitive,
demonstration.object[0]);
}
}
You should get output:
Old Values: 0, 0
New Values: 0, 1
Unchanged Values: 0, 1
Notice that the first value, the primitive, did not change when we incremented our primitiveParameter value, because it had already been passed by value and no longer had any relationship with the primitive field inside the object.
Setting objectParameter[0] did change the value inside our sample object because arrays are objects. When you say object = obj in a constructor you point object to the data that obj points to. Since they both point to the same place, they both see changes.

Static variables in java

I have scenario like this
public class Test{
static int a;
int b;
public static void main(String[] args){
Test t1 = new Test();
Test t2 = new Test();
}
}
What will be the variables in object t1 and object t2?
As per my understanding since variable a is a static variable it will be both in object 1 and object 2.
And b will be created separate copy for both the objects.
But when I assign a value to variable b ie(int b=1) and call it like System.out.println(t1.b), System.out.println(t2.b)
Instead of getting an error I am getting 1 as output from both the objects.
Why is that?
As per my understanding since variable a is static variable it will be both in object 1 and object 2.
No. It's not in either object. It exists without reference to any particular instance at all. Although Java allows you to refer to it "via" a reference, e.g. int x = t1.a; you shouldn't do so. You should instead refer to it via the class name (test.a in your case - although you should also start following Java naming conventions) to make it clear that it's static.
And b will be created separate copy for both the objects.
Yes.
But when I assign a value to variable b ie(int b=1) and call it like System.out.println(t1.b), System.out.println(t2.b) Instead of getting an error I am getting 1 as output from both the objects.
Well that's because you've basically given it an initial value to assign for each new object. That's entirely reasonable. There are still two independent variables:
t1.b = 2;
t2.b = 3;
System.out.println(t1.b); // Prints 2
System.out.println(t2.b); // Prints 3
Static variables are class members that are shared among all objects. There is only one copy of them in main memory. Static variables are created at run time on Heap area.
In case of yours...
int b = 1;
it's an assignment at class level, making 1 the default value for variable b(In normal case default value is 0). hence when you print it, its gives you the ans as 1 not error.
int b = 1; //initialized b to 1 for all obj of class Test
System.out.println(t1.b); // Prints 1
System.out.println(t2.b); // Prints 1
No, a static variable is not an instance variable but a class variable.
That's, every instance of this class shares the same reference of those variables.
Take a look at Understanding Class Members
Here a is static variable and b is instance or non-static variable.
For static variable, only one copy is created for all objects, where as for instance variable, one copy is created for each object.
Here when b=1, for every object of that Test class, one copy is created and it can access it through its object name. So output will be 1.
Of course that is exactly what it should output.
If you assign say,
int b=1;
that assignment is at class level, making 1 the default value for variable b.
However, if you assign like this:
t1.b=1;
that will assign 1 to only the copy of variable b in object t1.
Try it.
static variables are class variables. static variable are stored in static memory.
static variables are created to access inside main() method.
The static variables can be accessed by their class name, if they are present in outside class.
class sv {
static String name = "abc";
}
public class staticvariable {
static int t;
public static void main(String[] args) {
System.out.println("static variable is - "+t);
System.out.println(sv.name);
t=100;
System.out.println(t);
}
}

Advance for reference variables?

I am trying to understand the difference between Object with primitive variables when using them as parameters in a method.
There are some examples using reference variables:
public class Test1 {
public static void main(String[] args) {
int[] value = {1};
modify(value);
System.out.println(value[0]);
}
public static void modify(int[] v) {
v[0] = 5;
}
}
result: 5
public class Test2 {
public static void main(String agrs[]) {
Integer j = new Integer(1);
refer(j);
System.out.println(j.intValue());
}
public static void refer(Integer i) {
i = new Integer(2);
System.out.println(i.intValue());
}
}
result: 2 | 1
So what is different in here?
In java array is primitive type.and Integer is Object type.
For primitives it is pass by value the actual value (e.g. 3)
For Objects you pass by value the reference to the object.
In first example,
you are changing value in array.
while in other example ,
you are changing reference of i to other memory location where object value is 2.
when returning back to main function, as you are not returning value. its reference scope limited to "refer" method only.
Recall that the array references are passed by value. The array itself is an object, and that's not passed at all (That means that if you pass an array as an argument, your'e actually passing its memory address location).
In modify() method, you're assigning 5 to the first place in the array, hence, changing the array's value. So when you print the result, you get: 5 because the value has been changed.
In the second case, you're creating a new Object of type Integer locally. i will have the same value when you exit the method refer(). Inside it you print 2, then you print i, which is 1 and hence change doesn't reflect.
v[0] = 5, is like saying Get 0th element of current v's reference and make it 5.
i = new Integer(2), is like saying change i to 2's Integer object reference
In one case you are changing the internal values via the reference and in latter you are changing the reference itself.
The difference here is that they are different.
In your first example you are passing the argument to another method, which is modifying one of its elements, which is visible at the caller. In the second case you are assigning the variable to a new value, which isn't visible at the caller, because Java has pass-by-value semantics.
NB 'Primary variable' has no meaning in Java.
I don't know what the word 'advance' in your title has to do with anything.

Object value doesn't change

class smth{
public static void main(String[] args){
private Integer x = new Integer(17);
inc(x);
System.out.print("x="+x);
}
public static void inc(Integer x){
x++;
System.out.println("n="+x);
}
}
output:
n=18;
x=17;
Integer is an object and I don't understand why the value of x did not change in this case.
Cause Integer is immutable object. When you send it to method, new reference to it is created. When you do increment, reference inside method is reassigned to new Integer with value 18 but reference inside main is still referencing to old Integer with value 17.
Integer is immutable. The x++ creates a new object, and rebinds x to refer to it. The change does not propagate back to the caller since the reference to the original x was passed by value.
Any wrapper classes are immutable class.
Because x++, on an Integer object, actually means:
int temp = x.intValue();
temp++;
x = Integer.valueOf(temp);
The x variable is being assigned a new Integer instance. And since parameters are passed by value, the original reference stays unmodified.
It is because Java passes objects to methods by value and not by reference. Upon completing the method call, the object value will be the same in the calling method as it was before passing it. Within the called method, the value can change but the scope of the change is the method to which it was passed.
This is because Integer, a wrapper over the primitive int, is immutable, and Java passed object references by value. Any change made to the object reference inside the method has no effect on the object passed in: the reference is replaced with a reference to a new object, yet the original remains intact because it is immutable.
To address this issue, you need another level of indirection - you can use an array, a mutable int from apache commons, or roll your own suitably designed class.
public static void main(String argv[])
MutableInt x = new MutableInt (17);
inc(x);
System.out.print("x="+x.intValue());
}
public static void inc(MutableInt x){
x.add(1);
System.out.println("n="+x.intValue());
}
It is because the object modifying inside the method incis not the same as the one printed outside this method.
Inside the method inc x is a reference which points to an object. When you run x ++, that reassigns X to reference a new Integer object, with a different value. Thus, you are not modifying your original 'x' variable declared on the main.
You have to return the "pointer" to the new integer object:
public static int inc(Integer x){
x++;
System.out.println("n="+x);
return x;
}
public static void main(String argv[])
Integer x = new Integer(17);
x = inc(x);
System.out.print("x="+x);
}
An Integer, is a Object that contains a single int field. An
Integer is much bulkier than an int. It is sort like a Fedex box to
contain the int. Integers are immutable (source)

Categories

Resources