Wednesday, August 3, 2016

Java is passing object reference by value or reference ?

What is Pass by Value and Pass by reference?

These are the two way for passing parameters to the method or functions in programming languages.

Pass by Value or call by value

If we call a method by passing values to it, it is known as call by value.
 Whatever changes you are doing in the called method, will not affect the calling method.(unless and until you return that value from the method).

i.e In case of call by value original value is not changed

E.g

Public class passByValue {
Public static Void increment(int i)
{
            i =  i + 1; // i =11;
}

Calling part:

public static void main(String[] args) {      
int  i  = 10;
            increment(i);
            System.out.println(" i: " +i  ); // i  = 10;
}

Here value of ‘i ‘remain constant in outside increment. That is we are just passing values to the method.

Pass by Reference :

In the pass by reference we are passing the reference (reference to memory location) of the object not the value. So the calling parameter and method arguments both are pointing to same memory location, so change made to the values will affect both the caller and callee.
i.e In case of call by reference original value is changed if we made changes in the called method

In java there is no Pass by Reference , But for c and c++  there are Pass by Reference ,so taking the example from c to explain

E.g from C. – swap variables.

void swap(int *x, int *y) {

               int temp;
               temp = *x;    /* assigning temp to address of x */
               *x = *y;      /* assign x to y */
               *y = temp;    /* assigning y to temp */
             
               return;
            }
int main () {

               /* local variable definition */
               int a = 30;
               int b = 50;
             
               printf("Before swap, value of a : %d\n", a );
               printf("Before swap, value of b : %d\n", b );
               /* * &a ->  address of variable a
                  * &b ->  address of variable b.
               */
               swap(&a, &b);
               printf("After swap, value of a : %d\n", a );
               printf("After swap, value of b : %d\n", b );
             
               return 0;
            }
O/P :

Before swap, value of a :30
Before swap, value of b :50
After swap, value of a :50
After swap, value of b :30

In the above example we will be able to see the how to do a pass by reference. By passing ‘&a’ we are passing the reference of the ‘a’(address location of the a), so whatever changes made to this ‘a’ will reflect to the memory location. So if we don’t return also the same will reflect for calling program also.

But we know that in java there is no concept of pointers and passing the variables with ‘&’. So there is no concept of pass by reference in java.

There Exists only Pass by value in JAVA

In java we can do only pass by values (call by values) and passes the references by value.
If it is primitive type or if it is an object, everything we are passing to functions using values.

Java passes the references by value.

While hearing this, java don’t have pass by reference, we will be quite surprised!!!! Because every time we are hearing only, object , reference and instance in java, also  all object variables are references. But java doesn’t pass method parameters by references, it passes that by the references by value.

"Java manipulates objects 'by reference,' but it passes object references to methods 'by value.'" – From O'Reilly's Java in a Nutshell by David Flanagan

In java they are 2 types of parameters we are passing to the methods.

                     Primitive data types and Reference data types.

Primitive data type in Java are passed by value.
Reference data types are passed by object references by value

For Primitive we have already seen example in pass by value.

Pass object references by value – using Reference data types

Java copies and passes the reference by value, not the object. 

But these passed reference are just copies of the object references, not the original Object.

public class Employee {
            int number;
            String name;
            public static void increment(Employee emp) {
                        emp.number = emp.number +1;
            }
            public static void main(String[] args) {
                        Employee e = new Employee();
                        e.number = 1001;
                        increment(e);
                        System.out.println(e.number);
            }
}

When an object reference is passed to a method, the method gets a copy of the object reference.

So the passes and received arguments refer to same object.
Original reference and the parameter copy both will refer the same Java object.
So change in values of the reference from method reflect to both original and copy.
                                                                                                     


But from method (inside the method), we will be able to change the state of object, but that will not get reflected to the passed object, since we are passing only copy of reference.

            public static void increment(Employee emp) {
                        Employee emp1 = new Employee();
                        emp1.number = 2000;
                        emp = emp1;
                        System.out.println(emp.number);
            }

Consider the above example, here we are changing the state of object emp to emp1.So now change in emp.number will not reflect to e.number.







                                                                               

              

Value of e.number doesn’t change. But the value of Emp.number changed to ‘2000’.
That is reference by value are not actual object reference.


Swap will not work in java.

In the above in ‘Pass by Reference’ section you have seen a swap program, from C.
 But this will not work in java, since java doesn’t have pass by reference.

public class Employee {
            int number;
            String name;
            public static void swap(Employee emp1,Employee emp2) {
                        Employee temp = emp1;
                        emp1 = emp2;
                        emp2 = temp;
                        System.out.println("At the end of  swap method, value of e1.number : "+ emp1.number );
                        System.out.println("At the end of  swap method, value of e2.number : "+ emp2.number );
            }

            public static void main(String[] args) {
                        Employee e1 = new Employee();
                        e1.number = 1001;
                        Employee e2 = new Employee();
                        e2.number = 3001;
                        System.out.println("Before swap, value of e1.number :"+ e1.number );
                        System.out.println("Before swap, value of e2.number : "+ e2.number );

                        swap(e1,e2);
                        System.out.println("After swap, value of e1.number :"+ e1.number );
                        System.out.println("After swap, value of e2.number : "+ e2.number );
            }
}

O/P:
Before swap, value of e1.number :1001
Before swap, value of e2.number : 3001
At the end of  swap method, value of e1.number : 3001
At the end of  swap, value of e2.number : 1001
After swap, value of e1.number :1001
After swap, value of e2.number : 3001

From  the main() method we passed two objects e1 and e2 to swap() method and  those are received by swap() method as emp1 and emp2 references respectively. Then inside swap() method emp1  and emp2 are getting interchanged.
You will be able to see that inside the swap method both are interchanged.

At the end of  swap method, value of e1.number : 3001
At the end of  swap, value of e2.number : 1001

Inside the swap() , the state of object changed, so that will not reflected to the value of the reference.
So in main() program if we print after the swap() it is giving old values only

After swap, value of e1.number :1001
After swap, value of e2.number : 3001



Monday, August 1, 2016

Static Block – Static Initializer - Static initialization blocks – SIB – Class intializer

While hearing ‘Static’ itself, we will be sure that the state of this will be static, ie it does not depends on object (values will not vary for each object). For accessing static things (variable, method, block, class) no need to create an instances.

SIB is used to initialize Static variables. It is execute when a class is first loaded, before loading main method. It is executed for every class loading.
This is normal block and all the code will be enclosed in {} and it should preceded with static keyword.

Syntax:
static { …………………… }

E.g
public class staticblock {

                static int i;
    int j;
    
    // start of static block
    static {
        i = 10;
  // j = 5; : compilation error :  cannot make a static reference to non-static field 'j'
        System.out.println("First static block called .........i="+i);
    }
    // end of static block
   
    staticblock(){
        System.out.println("Constructor called .......value of i....." +i);
    }
    void test() {
                staticblock.i = staticblock.i +5; // i = i+5 also correct
                System.out.println("inside method test  .......value of i....." +i);
    }
    static {
        System.out.println("Second static block .........i="+i);
    }
    public static void main(String args[]) {
                 
    System.out.println(" Main is called .....");
    System.out.println("value of satic variable from main class ..i ="+i);
                staticblock s = new staticblock();
                s.test();
                staticblock s1 = new staticblock();
                s1.test();
                staticblock.staticMethod2();
               
    }
    static {
        staticMethod();
     //test(); : compilation error:can't make refernce to non-static method
        System.out.println("Third static block.........i="+i);
    }

    public static void staticMethod() {
                i = i +5;
        System.out.println("This is static method...i="+i);
    }

    public static void staticMethod2() {
        System.out.println("This is static method2...i="+i);
    }
}


Things to know:

·         Executes before main at the time of class loading :

o   Static Block are not declared in main method. Since its loading happening before the main method, when the class is loaded into JVMi.e. initializes when class load into memory, it means when JVM read the byte code.  So the creation of static block is happening before the main method.

·         Used to initialize static data members:

o   That variables that initialized in static blocks are shared by all the objects of that class. (You can thought it like constructor of a class !!!). This block is belong to class to initialize class variables(static variables).

·         A class can have any number of static initialization blocks. And they execute in the order as they appears in the class (in source code).And can written anywhere in the program (not inside main method)

·         JVM combines all the static blocks into a single static block, as the order in that they appears in the source and then execute. If the block contain any static methods then that also execute.

·         Static blocks will be called only once at the class loading time.

·         You can’t throw checked exceptions, no return statement , can’t use this and super reference from this ‘static block’

·         JVM Limitation : static initializer block should not exceed 64K

Where to use?

·         Class has static members that requires complex initialization
·         We want check some scenarios before execution of main block. E.g to find what O.S your using(wants to develop some applications that will run alone in windows)

  • For loading drivers.
E.g You want to initialize a JDBC driver connection. This connection is constant for all over the program

static connection conn = null;
static {
try {
Class.forName("com.mysql.jdbc.Driver");
Conn = DriverManager.getConnection(url,user,password);
} catch (SQLException se) {
se.printStackTrace();
}
}

·         For Logging purpose – For initializing loggers.