Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Nov 16, 2015

Is Java pass by reference or pass by value ?

Case 1: Pass by reference
Lets assume Java is pass-by-reference, so what should get printed on running below code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class A {

 String name;

 public static void main(String[] args) {
  callingMethod();
 }

 private static void callingMethod() {
  A myObj = new A();
  myObj.setName("I am from calling method");
  calledMethod(myObj);
  System.out.println(myObj.getName());
 }

 private static void calledMethod(A myObj) {
  myObj = new A();
  myObj.setName("I am from called method");
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}

It should be "I am from called method", right. But opposite to what we all thought, "I am from calling method" is the result, which gives an impression that Java is not pass by reference, but pass by value may be. Then lets test for pass by value nature.


Case 2: Pass by Value
Comment out the 17th line from the above code and see the result.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class A {

 String name;

 public static void main(String[] args) {
  callingMethod();
 }

 private static void callingMethod() {
  A myObj = new A();
  myObj.setName("I am from calling method");
  calledMethod(myObj);
  System.out.println(myObj.getName());
 }

 private static void calledMethod(A myObj) {
  // myObj = new A();
  myObj.setName("I am from called method");
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}

For pass by value, data in "myObj" in callingMethod should not get changed by changedMethod and "I am from calling method" should get printed. But instead, "I am from called method" is outputted this time.

So what is Java then, pass-by-value? or pass-by-reference?
Answer is pass-by-value. Do remember this, Java is always PASS-BY-VALUE. So, lets see what happened in both cases when "myObj" was passed from callingMethod to calledMethod.

Initially, when new Object is created at line 10, memory is allocated for that object in heap space and "myObj" starts pointing to that memory. At line 11, "name" property in object memory is set to "I am from calling method".

At line 12, when "myObj" is passed to the calledMethod, coy of the reference "myObj" is created and that copy is passed to the calledMethod. However, it points to the same memory in heap space as "myObj". When name is changed in the calledMethod, it is changed in the shared memory between the 2 references in callingMethod and calledMethod.

See what happened exactly in both cases:

Case 1:



Case 2:





I have tried to make the diagrams self explanatory. Please post in comment section for any query related to the article.

I hope above explanation helps to understand why Java is pass-by-value and not pass-by-reference.
Join us at +Java Territory to stay updated with latest articles. Thanks for reading.

Sep 9, 2015

Basics Revisited | SerialVersionUID

SerialVersionUID is one among the favorite topics in Java interview. Its important for Java programmer to understand its concept, not only for the interview but to use serialization in java. We will start by understanding what is SerialVersionUID  and how it is generated, and then move forward to see some code examples.



SerialVersionUID
SerialVersionUID is used to ensure that during deserialization the same class (that was used during serialize process) is loaded. 
Syntax:
ANY-ACCESS-MODIFIER final static long serialVersionUID = < value>
serialVersionUID is a static final field. You can assign any number of your choice to it. 

How serialVersionUID is generated?
During object serialization, the default Java serialization mechanism writes the metadata about the object, which includes the class name, field names and types, and superclass. This class definition is stored as a part of the serialized object. This stored metadata enables the deserialization process to reconstitute the objects and map the stream data into the class attributes with the appropriate type.
Every time an object is serialized the java serialization mechanism automatically computes a hash value, if you do not provide one in source. ObjectStreamClass's computeSerialVersionUID() method passes the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns a hash value. This value is the serialVersionUID of the class, also called suid.
So when the serialize object is retrieved, the JVM first evaluates the suid of the serialized class and compares the suid value with the one of the object. If the suid values match then the object is said to be compatible with the class and hence it is de-serialized. If not InvalidClassException exception is thrown.

However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations and can produce different serialVersionUID in different environments.

Demonstrate serialVersionUID

Initial class to be serialized has a serialVersionUID as 1L.
import java.io.Serializable;
 
public class Lion implements Serializable {
  private static final long serialVersionUID = 1L;
  private String sound;
 
  public Lion(String sound) {
    this.sound = sound;
  }
 
  public String getSound() {
    return sound;
  }
}
Test serialVersionUID:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
 
public class SerialVersionUIDTest {
  public static void main(String args[]) throws IOException, ClassNotFoundException {
    Lion leo = new Lion("roar");
    // serialize
    System.out.println("Serialization done.");
    FileOutputStream fos = new FileOutputStream("serial.out");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(leo);
 
    // deserialize
    FileInputStream fis = new FileInputStream("serial.out");
    ObjectInputStream ois = new ObjectInputStream(fis);
    Lion deserializedObj = (Lion) ois.readObject();
    System.out.println("DeSerialization done. Lion: " + deserializedObj.getSound());
  }
}

Output:

Serialization done.
DeSerialization done. Lion: roar
Now change serialVersionUID to 2L in Lion class.
  private static final long serialVersionUID = 2L;
Comment the “serialize” block (4 lines of code) in SerialVersionUIDTest. Now run it and you will get the following exception.
  1. Serialized Lion with serialVersionUID with 1L.
  2. Changed serialVersionUID to 2L and compiled and loaded the class.
  3. Deserialize the already serialized object and load it with the latest class.
  4. We get exception as serialVersionUID is not matching.
Exception in thread "main" java.io.InvalidClassException: Lion; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
                    at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
                    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
                    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
                    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
                    at java.io.ObjectInputStream.readObject0(Unknown Source)
                    at java.io.ObjectInputStream.readObject(Unknown Source)
                    at SerialVersionUIDTest.main(SerialVersionUIDTest.java:21)


Compatible or Incompatible changes to a serializable class
Simple Examples of compatible changes are:
  • Addition of a new field or class will not affect serialization, since any new data in the stream is simply ignored by older versions. The newly added field will be set to its default values when the object of an older version of the class is un-marshalled.
  • The access modifiers change (like private, public, protected or default) is compatible since they are not reflected in the serialized object stream.
  • Changing a transient field to a non-transient field is compatible change since it is similar to adding a field.
  • Changing a static field to a non-static field is compatible change since it is also similar to adding a field.


Some Simple Examples of incompatible changes are:
  • Changing implementation from Serializable to Externalizable interface cannot be done since this will result in the creation of an incompatible object stream.
  •  Deleting an existing Serializable fields will cause a problem.
  • Changing a non-transient field to a transient field is incompatible change since it is similar to deleting a field.
  • Changing a non-static field to a static field is incompatible change since it is also similar to deleting a field.
  • Changing the type of an attribute within a class would be incompatible, since this would cause a failure when attempting to read and convert the original field into the new field.
  • Changing the package of class is incompatible. Since the fully-qualified class name is written as part of the object byte stream.

If no suid is present, inspite of making compatible changes, JVM generates new suid, thus resulting in an exception if prior release version object is used.
The only way to get rid of the exception is to recompile and deploy the application again. If we explicitly mention the suid, then if any of the mentioned compatible changes are made the class need not to be recompiled. But for incompatible changes there is no other way than to compile again.

Hope you liked the post. Connect at +Java Territory  to stay tuned with latest updates.

Jun 15, 2015

Why constructors can't be static, final or abstract?

A Java constructor is always called without an object and are not allowed to be overridden, hence is implicitly final and implicitly static. Also it is meaningless for a Java constructor to be abstract.
Actually, constructors have a mixture of static and non-static semantics. You can't "call" a constructor on an instance, and it they are not inherited, or overridable. This is similar to the way static methods work. On the other hand, the body of a constructor can refer to this, and call instance methods ... like an instance method. And then there is constructor chaining, which is unique to constructors. But the real point is that these aspects are fixed, and there is no point allowing a redundant static modifier.
This means that the final and static modifiers would be redundant, and the abstract keyword would have no meaning at all.
Naturally, the Java designers didn't see in any point in allowing redundant and/or meaningless access modifiers on constructors ... so these are not allowed by the Java grammar.
It is strange that interface methods don't share the same design call where the public  and abstractmodifiers are also redundant, but allowed anyway. Perhaps there is some (ancient) historical reason for this. But either way, it cannot be fixed without rendering (probably) millions of existing Java programs uncompilable.