Showing posts with label JAVA. Show all posts
Showing posts with label JAVA. Show all posts

Tuesday, September 22, 2020

int[] and Integer[] arrays - What is the difference?

This image should help you to understand the difference:






int is a number, it's a primitive type.

Integer is an object.

When you have an array of Integers, you actually have an array of objects. Array of ints is an array of primitive types.

Since arrays are objects, they're allocated on the heap. If it's an array of ints, these ints will be allocated on the heap too, within the array.

Further adding. to this..

There is a difference at run-time.

int[] is an array of primitive int values. Integer[] is an "object" array, holding references to Integer objects.

Most important practical difference: int[] cannot hold null values.

int[] does store primitive types. And the array itself lives on the heap. However, those primitives are allocated as part of the array. They are not stored separately elsewhere on the heap. This is very similar to how a primitive field is part of an object instance: The object is on the heap, and its field is an integral part of that object (whereas for a non-primitive field, only the reference is stored inside the object and the target instance that reference points at is stored separately on the heap).


Ref : this link

Friday, January 3, 2020

Does notify/notifyall release the lock being held

I have to disagree with people who say notifyAll() releases the lock on the object over which waiting and notifying threads are being synchronized.
An example:
Consumer class contains a block:
synchronized(sharedObject){
if(sharedObject.isReadyToConsume() == false){
     sharedObject.wait();
}else {
    sharedObject.doTheThing();
    System.out.println("consumer consuming...");
 }
}
Scenario: Consumer class gets the lock on the sharedObject object, enters exclusively (it's inside the sync block) and sees that sharedObject has nothing ready yet (nothing to consume :) ) and it calls wait() method on the sharedObject. That way it releases the lock (stops the execution there!) and waits to be notified to continue when another Thread (Producer maybe) calls sharedObject.notify(); or sharedObject.notifyAll();. When it gets notified it continues from the wait() line
It's the sharedObject that keeps track of threads that asked it to be notified. When some Thread calls sharedObject.notifyAll() method the sharedObject will notify the waiting threads to wake up... Now, the tricky part is that a thread naturally releases the lock of the object when it reaches the end of its synchronized(sharedObject){} block. THe question is what happens if I call notifyAll() in that block??? notifyAll() wakes up the waiting threads, but the lock is still owned by the Thread that has just call notifyAll()
Look at the Producer snippet:
synchronized(sharedObject){
//We are exlusively working with sharedObject and noone can enter it
[... changing the object ...]
sharedObject.notifyAll();     //notifying the waiting threads to wake up

Thread.sleep(1000);           //Telling the current thread to go to sleep. It's holding the LOCK
System.out.println("awake...");
}
If notifyAll() would release the lock then the "awake..." would get printed out after the Consumer classes already start working with the sharedObject. This is not the case... The output shows that the Consumer is consuming the sharedObject after the Producer exits its sync block...
  • wait() - releases the lock and continues on the next line when it gets notified
  • notify(), notifyAll() - don't release the lock. They simply make waiting threads runnable again (not idle). They will have the right to enter when the current thread reaches the end of its sync block and the Thread scheduleder tells them that the lock has been released. The fight for the lock begins again

Thursday, January 2, 2020

Why does StringBuffer/StringBuilder not override equals or hashCode?

String str1 = new String("sunil");
String str2 = new String("sunil");

HashMap hm = new HashMap()
hm.put(str1,"hello");
hm.put(str2,"bye");
final hm:

hm = { sunil=bye }
In above code, str1 and str2 are two different String objects. Should they be added to the HashMap separately? The answer is NO. This is because before inserting/putting a value in HashMap, it internally checks and compares the hashCode values of str1, str2. Both return the same hashcode value because the String class overrides equals() and hashcode() methods. So upon executing hm.put(str2,"bye"); first key will get overriden with the new value. Now try this :

StringBuilder sb1 = new StringBuilder("sunil");
StringBuilder sb2 = new StringBuilder("sunil");

HashMap hm = new HashMap()
hm.put(sb1,"hello");//sb1 and sb2 will return different HashCode
hm.put(sb2,"bye");// StringBuffer/StringBuilder does not override hashCode/equals methods
final hm:

{sunil=hello, sunil=bye}
Both value will be added in hashMap because sb1 and sb2 both returns different hashcode. StringBuilder/ StringBuffer does not override equals() and hashCode() method.

Sun Microsystem wanted the programmer to allow adding 2 different String kind of Values in Hashtable or any other Hash Collections likes (HashSet,HashMap…),that’s the reason hashCode() and equals() were not overridden intentionally in StringBuffer,StringBuilder class.

Wednesday, January 1, 2020

How many objects will be created in this case string str="a"+"b"+"c" in Java?

No object is created at runtime.
The variable will be set to reference one object from the "constant pool".

Example

For this code:
public class MyClass {{
    String result = "a" + "b" + "c";
}}


Compiled using Oracle Java build 1.7.0_04-b20 you get this bytecode:

Constant pool:
   #1 = Class              #2             //  MyClass
   #2 = Utf8               MyClass
   #3 = Class              #4             //  java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Methodref          #3.#9          //  java/lang/Object."<init>":()V
   #9 = NameAndType        #5:#6          //  "<init>":()V
  #10 = String             #11            //  abc
  #11 = Utf8               abc
  #12 = Utf8               LineNumberTable
  #13 = Utf8               LocalVariableTable
  #14 = Utf8               this
  #15 = Utf8               LMyClass;
  #16 = Utf8               SourceFile
  #17 = Utf8               MyClass.java
{
  public MyClass();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=1
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: ldc           #10                 // String abc
         6: astore_1
         7: return
      LineNumberTable:
        line 2: 0
        line 3: 4
        line 2: 7
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       8     0  this   LMyClass;
}


However, concatenating three String variables like this:
public class MyClass {{
    String a = "a";
    String b = "b";
    String c = "c";
    String result = a + b + c;
}}



and the compiler will instead use a StringBuilder like this:
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: ldc           #10                 // String a
         6: astore_1
         7: ldc           #12                 // String b
         9: astore_2
        10: ldc           #14                 // String c
        12: astore_3
        13: new           #16                 // class java/lang/StringBuilder
        16: dup
        17: aload_1
        18: invokestatic  #18                 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
        21: invokespecial #24                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
        24: aload_2
        25: invokevirtual #27                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        28: aload_3
        29: invokevirtual #27                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        32: invokevirtual #31                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        35: astore        4
        37: return

Friday, December 13, 2019

What are compatible and incompatible changes in Serialization process?

Compatible Changes :  Compatible changes are those changes which does not affect deSerialization process even if class was updated after being serialized (provided serialVersionUID has been declared)
 Adding new fields - We can add new member variables in class.
 Adding writeObject()/readObject()  methods - We may add these methods to customize serialization process.
 Removing writeObject()/readObject() methods - We may remove these methods and then default customization process will be used.
 Changing access modifier of a field - The change to access modifiers i.e. public, default, protected, and private have no effect on the ability of serialization to assign values to the fields.
 Changing a field from static to non static OR changing transient filed to non transient field. - it’s like addition of fields.

InCompatible Changes :  InCompatible changes are those changes which affect deSerialization process if class was updated after being serialized (provided serialVersionUID has been declared)
 Deletion of fields.
 Changing a nonstatic field to static or  non transient field to transient field. - it’s equal to deletion of fields.
 Modifying the writeObject() / readObject() method - we must not modify these method, though adding or removing them completely is compatible change.

Enum Tricky Questions

Java enumis a kind of a compiler magic. In byte code, any enum is represented as a class that extends the abstract class java.lang.Enum and has several static members. Therefore, enum cannot extend any other class orenum: there is no multiple inheritance.

Class cannot extend enum, as well. This limitation is enforced by the compiler.

Here is a simple enum:

enum Color {red, green, blue}


This class tries to extend it:

class SubColor extends Color {}


This is the result of an attempt to compile class SubColor:

$ javac SubColor.java
SubColor.java:1: error: cannot inherit from final Color
class SubColor extends Color {}
                       ^
SubColor.java:1: error: enum types are not extensible
class SubColor extends Color {}
^
2 errors


Enum cannot either extend or be extended. So, how is it possible to extend its functionality? The key word is "functionality." Enumcan implement methods.


https://dzone.com/articles/enum-tricks-two-ways-to-extend-enum-functionality

Wednesday, December 11, 2019

Different Ways to Create Objects in Java


Using the new keyword
The constructor gets called
Using newInstance() method of Class class
The constructor gets called
Using newInstance() method of Constructor class
The constructor gets called
Using clone() method
No constructor call
Using deserialization
No constructor call


Ref: https://dzone.com/articles/5-different-ways-to-create-objects-in-java-with-ex

Thursday, December 5, 2019

JUNIT



https://www.javaguides.net/2018/07/junit-4-annotations-with-examples.html

https://www.javaguides.net/2018/07/junit-5-assertions-with-examples.html

https://www.javaguides.net/2018/07/junit-4-aggregating-tests-in-suites.html

https://www.vogella.com/tutorials/Mockito/article.html

https://dzone.com/articles/a-guide-to-mocking-with-mockito

https://www.javaguides.net/2018/09/spring-boot-2-rest-apis-integration-testing.html

Tuesday, December 3, 2019

Core Java Interview Questions | Very important

1- Why main() in java is declared as public static void main?
Why public? In java public is access modifier and it using when we want to method from any where like any native library JNDI, etc. So that is reason main method is public, it can be accessible everywhere and to every object which may desire to use it for launching the application.

Why static? In java static is a keyword and it tells the compiler that particular entity belongs to a class and should be loaded once the JVM starts. So static things we could invoke without creating instance of that class. Lets suppose we do not have main method as static. Now, to call any method you need an instance of it. Now how to create instance of class which have main method and which one should be used and from where the parameters for overloaded constructors will come.

Why void? In void use before the method definition its mean this method is not returning any to the caller of method. But main method is invoked by JVM so there is no use of returning any value to JVM. The only thing application would like to communicate to invoking process normal or abnormal termination. This is already possible using System.exit(int). A non-zero value means abnormal termination otherwise everything was fine.

2- Does Java Pass by Reference or Pass by Value?
Java is pass by value and not pass by reference i.e. Java copies and passes the reference by value, not the object. Thus, method manipulation will alter the objects, since the references point to the original objects. But if you change the reference inside method, original reference will not get change. If it was pass by reference, then it would have got changed also. Well, primitive types are always pass by value without any confusion. But, the concept should be understood in context of method parameter of custom types.

Initializing a final variable :
We must initialize a final variable, otherwise compiler will throw compile-time error.A final variable can only be initialized once, either via an initializer or an assignment statement. There are three ways to initialize a final variable :

You can initialize a final variable when it is declared.This approach is the most common. A final variable is called blank final variable,if it is not initialized while declaration. Below are the two ways to initialize a blank final variable.
A blank final variable can be initialized inside instance-initializer block or inside constructor. If you have more than one constructor in your class then it must be initialized in all of them, otherwise compile time error will be thrown.
A blank final static variable can be initialized inside static block.

Hashmap Performance Improvements in Java 8

The Problem:
Until Java 7, java.util.Hashmap implementations always suffered with the problem of Hash Collision, i.e. when multiple hashCode() values end up in the same bucket, values are placed in a Linked List implementation, which reduces Hashmap performance from O(1) to O(n).

The Solution:
Improve the performance of java.util.HashMap under high hash-collision conditions by using balanced trees rather than linked lists to store map entries.This will improve collision performance for any key type that implements Comparable.

This JDK 8 change applies only toHashMap, LinkedHashMap, and ConcurrentHashMap.
The principal idea is that once the number of items in a hash bucket grows beyond a certain threshold (TREEIFY_THRESHOLD), that bucket will switch from using a linked list of entries to a balanced tree. In the case of high hash collisions, this will improve worst-case performance from O(n) to O(log n), and when they become too small (due to removal or resizing) they are converted back to Linked List.

static final int TREEIFY_THRESHOLD = 8;
static final int UNTREEIFY_THRESHOLD = 6;
Also note that in rare situations, this change could introduce a change to the iteration order of HashMap and HashSet. A particular iteration order is not specified for HashMap objects – any code that depends on iteration order should be fixed.

https://stackoverflow.com/questions/29740709/example-of-an-immutable-class-with-hashmap

https://www.geeksforgeeks.org/prevent-singleton-pattern-reflection-serialization-cloning/


https://www.javaguides.net/2018/11/java-8-interview-questions-and-answers.html


https://stackoverflow.com/questions/4055634/same-class-name-in-different-packages/29786782

http://java-performance.info/string-intern-in-java-6-7-8/

https://www.java67.com/2014/08/difference-between-string-literal-and-new-String-object-Java.html

Wednesday, November 27, 2019

Order of execution of Initialization blocks and Constructors in Java

Initializer block : contains the code that is always executed whenever an instance is created. It is used to declare/initialize the common part of various constructors of a class.
Constructors : are used to initialize the object’s state. Like methods, a constructor also contains collection of statements(i.e. instructions) that are executed at time of Object creation.

Order of execution of Initialization blocks and constructor in Java

1. Static initialization blocks will run whenever the class is loaded first time in JVM
2. Initialization blocks run in the same order in which they appear in the program.
3. Instance Initialization blocks are executed whenever the class is initialized and before constructors are invoked. They are typically placed above the constructors within braces.

OOPS Concepts

What is an Object?
In short, Object is an instance of a class. The Object is the real-time entity having some state and behavior. In Java, Object is an instance of the class having the instance variables as the state of the object and the methods as the behavior of the object. The object of a class can be created by using the new keyword.

A class is a group of objects which have common properties. It is a template or blueprint from which objects are created. In short, a class is the specification or template of an object.

What is Abstraction and give real-world examples?
Abstraction means hiding lower-level details and exposing only the essential and relevant details to the users.
Real world example
A car abstracts the internal details and exposes to the driver only those details that are relevant to the interaction of the driver with the car.

In Java, abstraction is achieved by Interfaces and Abstract classes. We can achieve 100% abstraction using Interfaces.
For details : https://www.javaguides.net/2018/08/abstraction-in-java-with-example.html

What is Encapsulation and give real-world examples?
Encapsulation refers to combining data and associated functions as a single unit. In OOP, data and functions operating on that data are combined together to form a single unit, which is referred to as a class.
For example - if a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class.
Encapsulation is implemented using private, package-private and protected access modifiers.

Difference between Abstraction and Encapsulation
Abstraction and Encapsulation in Java are two important Object-oriented programming concept and they are completely different from each other.
Encapsulation is a process of binding or wrapping the data and the codes that operate on the data into a single entity. This keeps the data safe from outside interface and misuse.
Abstraction is the concept of hiding irrelevant details. In other words, make the complex system simple by hiding the unnecessary detail from the user.
Abstraction is implemented in Java using interface and abstract class while Encapsulation is implemented using private, package-private and protected access modifiers.
Abstraction solves the problem at the design level. Whereas Encapsulation solves the problem at the implementation level.



Encapsulation: Information hiding.
Abstraction: Implementation hiding.

What is Polymorphism

The process of representing one form in multiple forms is known as Polymorphism.

Types of Polymorphism in Java
Compile time polymorphism or method overloading or static banding
Runtime polymorphism or method overriding or dynamic binding

Java Runtime Polymorphism with Data Member
The method is overridden not applicable data members, so runtime polymorphism can't be achieved by data members.
In the example given below, both the classes have a data member speedlimit, we are accessing the data member by the reference variable of Parent class which refers to the subclass object. Since we are accessing the data member which is not overridden, hence it will access the data member of Parent class always.




What is Composition?
Composition is an association represents a part of a whole relationship where a part cannot exist without a whole.

This is Order class, which HAS-A composition association with LineItem class. That means if you delete Order, then associated all LineItem must be deleted.

class Order {
    private int id;
    private String name;
    private List<LineItem> lineItems;
}

What is Aggregation?
Aggregation is an association represents a part of a whole relationship where a part can exist without a whole. It has a weaker relationship.

Sunday, November 24, 2019

Serialization Interview Questions

What is Serialization in java?
Serialization is process of converting object into byte stream.
 Serialized object (byte stream) can be:
 >Transferred over network.
 >Persisted/saved into file.
 >Persisted/saved into database.
Once, object have have been transferred over network or persisted in file or in database, we could deserialize the object and retain its state as it is in which it was serialized

How do we Serialize object, write a program to serialize and deSerialize object and persist it in file ?
In order to serialize object our class needs to implement java.io.Serializable interface. Serializable interface is Marker interface i.e. it does not have any methods of its own, but it tells Jvm that object has to converted into byte stream.

SERIALIZATION>
Create object of ObjectOutput and give it’s reference variable name oout and call writeObject() method and pass our employee object as parameter [oout.writeObject(object1) ]


OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, serializing employee objects...");
oout.writeObject(object1);


DESERIALIZATION>
Create object of ObjectInput and give it’s reference variable name oin and call readObject() method [oin.readObject() ]

InputStream fin=new FileInputStream("ser.txt");
ObjectInput oin=new ObjectInputStream(fin);
System.out.println("DeSerialization process has started, displaying employee objects...");
Employee emp;
emp=(Employee)oin.readObject();


Difference between Externalizable and Serialization interface (Important)?


Methods
It is a marker interface it doesn’t have any method.
It’s not a marker interface.
It has method’s called writeExternal() and readExternal()
Default Serialization process
YES, Serializable provides its own default serialization process, we just need to implement Serializable interface.
NO, we need to override writeExternal() and readExternal() for serialization process to happen.
Customize serialization process
We can customize default serialization process by defining following methods in our class >readObject() and writeObject()  
Note: We are not overriding these methods, we are defining them in our class.
Serialization process is completely customized
We need to override Externalizable interface’s writeExternal() and readExternal() methods.
Control over Serialization
It provides less control over Serialization as it’s not mandatory to define readObject() and writeObject() methods.
Externalizable provides you great control over serialization process as it is important to override  writeExternal() and readExternal() methods.
Constructor call during deSerialization
Constructor is not called during deSerialization.
Constructor is called during deSerialization.


How can you customize Serialization and DeSerialization process when you have implemented Serializable interface ?
Answer.  Here comes the quite challenging question, where you could prove how strong your Serialization concepts are.We can customize Serialization process by defining writeObject()  method & DeSerialization process by defining readObject() method.

Let’s customize Serialization process by defining writeObject()  method :

      private void writeObject(ObjectOutputStream os) {
           System.out.println("In, writeObject() method.");   
           try {
                  os.writeInt(this.id);
                  os.writeObject(this.name);
           } catch (Exception e) {
                  e.printStackTrace();
           }
    }
We have serialized id and name manually by writing them in file.
 
Let’s customize DeSerialization process by defining readObject()  method :

    private void readObject(ObjectInputStream ois) {
           System.out.println("In, readObject() method.");
           try {
                  id=ois.readInt();
                  name=(String)ois.readObject();
           } catch (Exception e) {
                  e.printStackTrace();
           }
    }

We have DeSerialized id and name manually by reading them from file.

How can you avoid certain member variables of class from getting Serialized?

Answer. Mark member variables as static or transient, and those member variables will no more be a part of Serialization.

What is serialVersionUID?
The serialization at runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization.

What are compatible and incompatible changes in Serialization process?
Compatible Changes :  Compatible changes are those changes which does not affect deSerialization process even if class was updated after being serialized (provided serialVersionUID has been declared)
 Adding new fields - We can add new member variables in class.
 Adding writeObject()/readObject()  methods - We may add these methods to customize serialization process.
 Removing writeObject()/readObject() methods - We may remove these methods and then default customization process will be used.
 Changing access modifier of a field - The change to access modifiers i.e. public, default, protected, and private have no effect on the ability of serialization to assign values to the fields.
 Changing a field from static to non static OR changing transient filed to non transient field. - it’s like addition of fields.

InCompatible Changes :  InCompatible changes are those changes which affect deSerialization process if class was updated after being serialized (provided serialVersionUID has been declared)
 Deletion of fields.
 Changing a nonstatic field to static or  non transient field to transient field. - it’s equal to deletion of fields.

 Modifying the writeObject() / readObject() method - we must not modify these method, though adding or removing them completely is compatible change.

What if Serialization is not available, is any any other alternative way to transfer object over network?
>We can can convert JSON to transfer the object. JSON is helpful in stringifying and de stringifying object.
>Hibernate (ORM tool) helps in persisting object as it in database and later we can read persisted object.
>We can convert object into XML (as done in web services) and transfer object over network.

Why static member variables are not part of java serialization process (Important)?
Answer. Serialization is applicable on objects or primitive data types only, but static members are class level variables, therefore, different object’s of same class have same value for static member.
So, serializing static member will consume unnecessary space and time.
Also, if modification is made in static member by any of the object, it won’t be in sync with other serialized object’s value.

What is significance of transient variables?
Answer. Serialization is not applicable on transient variables (it helps in saving time and space during Serialization process), we must mark all rarely used variables as transient. We can initialize transient variables during deSerialization by customizing deSerialization process.

What will happen if one the member of class does not implement Serializable interface (Important)?
Answer. This is classy question which will check your in depth knowledge of Serialization concepts. If any of the member does not implement Serializable than  NotSerializableException is thrown.

What will happen if we have used List, Set and Map as member of class?
Answer. This question which will check your in depth knowledge of Serialization and Java Api’s. ArrayList, HashSet and HashMap implements Serializable interface, so if we will use them as member of class they will get Serialized and DeSerialized as well.

Are primitive types part of serialization process in java?
Yes, primitive types are part of serialization process.

Is constructor of class called during DeSerialization process?
Answer. This question which will check your in depth knowledge of Serialization and constructor chaining concepts. It depends on whether our object has implemented Serializable or Externalizable.
If Serializable has been implemented - constructor is not called during DeSerialization process.
But, if Externalizable has been implemented - constructor is called during DeSerialization process.

What values will int and Integer will be initialized to during DeSerialization process if they were not part of Serialization?
Answer.  int will be initialized to 0 and Integer will be initialized to null during DeSerialization (if they were not part of Serialization process).

How you can avoid Deserialization process creating another instance of Singleton class (Important)?
Answer. This is another classy and very important question which will check your in depth knowledge of Serialization and Singleton concepts. I’ll prefer you must understand this concept in detail. We can simply use readResove() method to return same instance of class, rather than creating a new one.

Defining readResolve() method ensures that we don't break singleton pattern during DeSerialization process.
   
  private Object readResolve() throws ObjectStreamException {
       return INSTANCE;
  }

Also define readObject() method, rather than creating new instance, assign current object to INSTANCE like done below :
  private void readObject(ObjectInputStream ois) throws IOException,ClassNotFoundException{
        ois.defaultReadObject();
        synchronized (SingletonClass.class) {
         if (INSTANCE == null) {
               INSTANCE = this;
         }
        }
  }

Can you Serialize Singleton class such that object returned by Deserialization process  is in same state as it was during Serialization time (regardless of any change made to it after Serialization)  (Important)?
Answer. It’s another very important question which will be important in testing your Serialization and Singleton related concepts, you must try to understand the concept and question in detail.
YES, we can Serialize Singleton class such that object returned by Deserialization process is in same state as it was during Serialization time (regardless of any change made to it after Serialization)


Defining readResolve() method ensures that we don't break singleton pattern during DeSerialization process.
   
  private Object readResolve() throws ObjectStreamException {
       return INSTANCE;
  }

Also define readObject() method, rather than creating new instance, assign current object to INSTANCE like done below :
  private void readObject(ObjectInputStream ois) throws IOException,ClassNotFoundException{
        ois.defaultReadObject();
        synchronized (SingletonClass.class) {
         if (INSTANCE == null) {
               INSTANCE = this;
         }
        }
  }

Purpose of serializing Singleton class OR  purpose of saving singleton state?
Answer. Let’s take example of our laptop, daily eod we need to shut it down, but rather than shutting it down hibernate (save state of  laptop) is better option because it enables us to resume at same point where we leaved it, like wise serializing singleton OR saving state of Singleton can be very handy.

How can subclass avoid Serialization if its superClass has implemented Serialization interface ?
If superClass has implemented Serializable that means subclass is also Serializable (as subclass always inherits all features from its parent class), for avoiding Serialization in sub-class we can define writeObject() method and throw NotSerializableException().
private void writeObject(ObjectOutputStream os) throws NotSerializableException {
        throw new NotSerializableException("This class cannot be Serialized");
}

Key Points :

Even though serialVersionUID is a static field, it gets serialized along with the object. This is one exception to the general serialization rule that, “static fields are not serialized”.

serialVersionUID is a must in serialization process. But it is optional for the developer to add it in java source file. If you are not going to add it in java source file, serialization runtime will generate a serialVersionUID and associate it with the class. The serialized object will contain this serialVersionUID along with other data.

The serialVersionUID for dynamic proxy classes and enum types always have the value 0L
transient and static fields are ignored in serialization. After deserialization transient fields and non-final static fields will be null.
final and static fields still have values since they are part of the class data.

ObjectOutputStream.writeObject(obj) and ObjectInputStream.readObject() are used in serialization and deserialization.
During serialization, we need to handle IOException; during deserialization, we need to handle IOException and ClassNotFoundException. So the deserialized class type must be in the classpath.
Uninitialized non-serializable, non-transient instance fields are tolerated.
When adding “private Thread th;“, no error in serializable. However, “private Thread threadClass = new Thread();” will cause exception:

Console
Exception in thread "main" java.io.NotSerializableException: java.lang.Thread
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at com.howtodoinjava.demo.serialization.DemoClass.writeOut(DemoClass.java:42)
at com.howtodoinjava.demo.serialization.DemoClass.main(DemoClass.java:27)
Serialization and deserialization can be used for copying and cloning objects. It is slower than regular clone, but can produce a deep copy very easily.
If I need to serialize a Serializable class Employee, but one of its super classes is not Serializable, can Employee class still be serialized and deserialized? The answer is yes, provided that the non-serializable super-class has a no-arg constructor, which is invoked at deserialization to initialize that super-class.
We must be careful while modifying a class implementing java.io.Serializable. If class does not contain a serialVersionUID field, its serialVersionUID will be automatically generated by the compiler.
Different compilers, or different versions of the same compiler, will generate potentially different values.


How serialVersionUID is generated?
serialVersionUID is a 64-bit hash of the class name, interface class names, methods and fields. Serialization runtime generates a serialVersionUID if you do not add one in source.

Computation of serialVersionUID is based on not only fields, but also on other aspect of the class like implement clause, constructors, etc. So the best practice is to explicitly declare a serialVersionUID field to maintain backward compatibility. If we need to modify the serializable class substantially and expect it to be incompatible with previous versions, then we need to increment serialVersionUID to avoid mixing different versions.



Sunday, November 17, 2019

Why Object.clone() is protected

It is not necessary to define our method by the name of clone. We can give it any name we want, e.g. createCopy(). Actually we are not overriding the Object.clone() method here, so we don’t have to follow any specification. Object.clone() is protected by its definition, so, practically, child classes of Object outside the package of the Object class (java.lang) can only access it through inheritance and within itself.

Ref: https://dzone.com/articles/shallow-and-deep-java-cloning

String.intern in Java 6, 7 and 8 – string pooling

  • Stay away from String.intern() method on Java 6 due to a fixed size memory area (PermGen) used for JVM string pool storage.
  • Java 7 and 8 implement the string pool in the heap memory. It means that you are limited by the whole application memory for string pooling in Java 7 and 8.
  • Use -XX:StringTableSize JVM parameter in Java 7 and 8 to set the string pool map size. It is fixed, because it is implemented as a hash map with lists in the buckets. Approximate the number of distinct strings in your application (which you intend to intern) and set the pool size equal to some prime number close to this value multiplied by 2 (to reduce the likelihood of collisions). It will allow String.intern to run in the constant time and requires a rather small memory consumption per interned string (explicitly used Java WeakHashMap will consume 4-5 times more memory for the same task).
  • The default value of -XX:StringTableSize parameter is 1009 in Java 6 and Java 7 until Java7u40. It was increased to 60013 in Java 7u40 (same value is used in Java 8 as well).
  • If you are not sure about the string pool usage, try -XX:+PrintStringTableStatistics JVM argument. It will print you the string pool usage when your program terminates.
Ref: http://java-performance.info/string-intern-in-java-6-7-8/