Some years back when I was learning Java, I got to know that Java follows Object Oriented Programming paradigm and everything in Java is an object either it is a String (which was a char array in C) or an array itself.

But later on I found on the internet, people are saying that Java is actually not a purely object-oriented because everything in Java is not an object, for example:
  1. All primitive types (char, boolean, byte, short, int, long, float, double) are not objects because we can not perform any object related operation (using . and calling methods) on them.
  2. I have seen some people some saying that all the static content (variables and methods) does not belong to any object so they are non-object things.
I easily accepted these reasons and started to believe that Java is not a pure object-oriented programming language.

But later on, I found that for every object JVM creates two objects
  1. The object itself.
  2. And one Class level object which gets created only once when classloader loads the class into memory. And all static content of that class belongs to this Class object and all other objects of that class refer to this class level object for all static content.
For Example for below statement, there will be two objects

Employee emp = new Employee();

One is emp itself and another one is the class level object of employee class. If we are accessing any static content through the emp object it points to the class level object to access that.

That's the reason why static variables get changed for every object even if we change it for a single emp object because all objects are pointing to the same copy of that variable from class level object.

Now 2nd point got canceled because the static content does belong to an object. But the 1st point is still there and we still have primitive data types which are not objects in Java. However wrapper classes are there and due to autoboxing (automatic unboxing-boxing, boxing-unboxing), we can directly assign a primitive literal to its Wrapper class reference.

But still, we can’t perform object related operations on primitives variables we always need to create objects of the respective wrapper class, for example

Integer obj = new Integer(5); // here we can do obj.toString()
int i = 5; // but we can't do i.toString() here

And due to these reasons, we say primitive types are not objects but what if that’s actually an elusion and it is end-user perspective (Java developers are end user to Java because we are using it not creating it).

If we dig down deep into the Java source codes we can find that JVM internally treats all primitive types as objects and proof of this can be found in source code or Javadoc of class Class, according to source code class Class

Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects

And Javadoc code of Class.isPrimitive() method says

public boolean isPrimitive()
Determines if the specified Class object represents a primitive type.
There are nine predefined Class objects to represent the eight primitive types and void. These are created by the Java Virtual Machine, and have the same names as the primitive types that they represent, namely boolean,byte, char, short, int, long, float, and double.
These objects may only be accessed via the following public static final variables, and are the only Class objects for which this method returns true.
Returns:
true if and only if this class represents a primitive type
Since:
JDK1.1
See Also:
Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE

If we open source code of class Class and do a CTRL + F for "primitive” word we will find lots of reason to believe that JVM treats all primitive types as objects internally.

Also if we open source of the Integer class search for Integer.TYPE entry, we will find

public static final Class[Integer](https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html) TYPE
The Class instance representing the primitive type int.

And if we write below the line in your program in eclipse

Integer.TYPE i = 5;

We get a compilation error saying Integer.TYPE cannot be resolved to a type with a hint from eclipse to change it to int.

So if all primitive types are objects for JVM then why should we use primitive types

primitive-type-and-wrapper-classes-in-java

If JVM creates objects for all primitive types then why do we need to use primitive types instead of creating an object of its respective wrapper classes. That’s because JVM creates these native objects for primitive types internally and those objects are very lightweight and optimized than their respective wrapper class objects and due to this, they have less functionality e.g. we can’t call methods on them because they don’t have any.

We should use primitive types because:
  1. They are fast e.g. below program takes 9 seconds to run on my machine while it takes 0 seconds if I convert Long sum to long sum.
     public static void main(String[] args) {
 long millis = System.currentTimeMillis();
 Long sum = 0L; // uses Long, not long
 for (long i = 0; i <= Integer.MAX_VALUE; i++) {
  sum += i;
 }                     

 System.out.println(sum);

 System.out.println((System.currentTimeMillis() - millis) / 1000);
  1. They allow us to use native equality operator ==
     new Integer(3) == new Integer(3); // false
     new Integer(100) == new Integer(100); // false
     Integer.valueOf(5) == Integer.valueOf(5); //true
     Integer.valueOf(100) == Integer.valueOf(100); //false

4th statement gives false because the 256 integers closest to zero [-128; 127] are cached by the JVM, so they return the same object for those. Beyond that range, they aren't cached, so a new object is created.

So there are enough reasons to say JVM treats all primitive types as objects internally, however, we can’t use them in that way and we have got Wrapper classes for that.

This is why Java is purely Object Oriented Language, Please mention in comments what do you think Java is a purely Object Oriented Language or not.
Java 8 is one of most popular release in the history of Java and have introduced lots of major features like Lambda Expression, Method Reference, Stream API, new DateTime API, Default and static interface methods etc.. For complete list of new Java 8 feature read What’s New in JDK 8 article by oracle itself.

In this article, we are going to study Java Lambda Expression in details e.g. what is the lambda expression, why it so popular, what are the advantages of the lambda expression, what purpose is solved, how it differs from anonymous classes and why/how should we use it.
lambda expression logo

Why Java needs Lambda Expression

Java is a multiparadigm programming language (Supports Object Oriented, Imperative, Structured, Declarative style of programming). However, most of its design architecture is influenced by Object Oriented programming style.

And there are two variations of object-oriented programming (OOP) style
  • Class-based OOP style
  • Prototype-based OOP style → doesn’t support inheritance
Java supports class-based OOP style that’s why there should be a class for every object while JavaScript follows Prototype-based OOP style that’s why we don’t have the concept of class and inheritance in JavaScript. Everything in JavaScript is an object either it is a variable or a function while in Java a function (method) is state of the object.

Apart from this JavaScript also follows the Functional style of programming so we can assign functions to variables, pass functions as argument or return a function from other function etc..

Due to class-based nature of Java programming, it is hard to maintain functions as first class citizen similar as objects. That’s why Java does not support functional style of programming (before Java 8) and we can’t assign functions to variables or pass functions as argument or return them.

Lambda Expression is a way to introduce functional programming to Java. So by using lambda expression we can simply define and use functions wherever we need them (e.g. inside a method) without even creating objects. Due to lambda expression now functions have also become first class citizens in Java language.

What is Lambda Expression

By definition

A Lambda Expression is an anonymous function (a function defined, and possibly called, without being bound to an identifier and a name.

The concept is similar to anonymous classes or anonymous objects, Now we can declare methods wherever we want them without any name. The sole purpose of writing an anonymous class object is to override its method and provide our own functionality but for that single method, we always need to declare the class. With lambda expression, we can eliminate the declaration of the anonymous class and we can simply write the methods.

Since the old days of Swing, we always had written anonymous classes if we wanted to pass some functionality to any method. For example old event listener code and thread creation code look like

Runnable runnable = new Runnable() {
  @Override
  public void run() {
  System.out.println("Running thread using anonymous class");
  }
};
Thread thread = new Thread(runnable);

If you look at above code the actual functionality of the thread is written in the run() method. And we are creating an anonymous class object just to define a single method which is really unnecessary if we can do functional programming (just create the function where it needs). So here the creation of anonymous class Can be replaced by lambda as below which is just a single line of code:

Runnable runnable = () -> System.out.println("Running thread using lambda expression");
Thread thread = new Thread(runnable);

Above we have assigned a lambda to the reference variable but more precisely we create a thread as below if r is not reusable.

Thread t = new Thread(() -> System.out.println("Running thread using lambda expression"));

How to write Lambda Expression

Through lambda expression, we can write functional code but this is still not similar to other functional programming languages like C, C++, JavaScript.

Java is still a class based object oriented language and methods always belong to some class, abstract class or interface. So methods implemented using lambda expression must have to define somewhere. So along with Lambda Expression Oracle engineers have applied some tweaks and introduced the concept of Functional Interfaces.

Functional Interface → An interface with only one abstract method and optionally annotated with @FunctionalInterface annotation.

We can use lambda expressions only with Functional interfaces, in above example the Runnable interface is a functional interface.
Lambda expressions in Java is usual written using syntax (argument) -> (body)

lambda expression syntax

Converting anonymous classes to Lambda Expression

After little bit practice, you will not feel any need for conversion, you will start writing lambdas without any confusion. But whenever you got confused conversion approach is the best way to create lambdas.

We can convert the old anonymous class code to lambda expression as below, suppose we want to create lambda expression for thread generation process:

Runnable runnable = new Runnable() {
  @Override
  public void run() {
  System.out.println("In thread");
  System.out.println("doing something");
  }
};

Remove below things in order
→ new keyword new,
→ class name and it’s parentheses Runnable(),
→ class opening and closing braces { };,
@Override annotation (if have any),
→ remove method declaration (leave argument parentheses ()) public void run
→ removing method opening { and closing braces } is not necessary, however, if you have single line of code in it then you can remove them
→ add -> between parentheses () and execution code inside { }

Runnable runnable = new Runnable() {
  @Override
  public void run() -> {
  System.out.println("In thread");
  System.out.println("doing something");
  }
};

So now our lambda expression will become

Runnable runnable = () -> {
  System.out.println("In thread");
  System.out.println("doing something");
}


Single line Zero Argument method: If we have a single line of code inside execution block {} then we can remove them.

Runnable r = () -> System.out.println("In thread");

Multiple Argument Methods: If functional interface’s method definition have arguments then we can write them inside ()

Comparator<Integer> comparator = (Integer i, Integer j) -> i.compareTo(j);

Single Argument Methods: And if there is only one argument then we can eliminate () braces
Consumer<String> consumer = obj -> System.out.println(obj);

Difference between Lambda Expression and Anonymous class

  • An anonymous class object creates a separate class file after compilation which increases the size jar while after compilation Lambda expression becomes invokedynamic which dynamic language implementation.
  • We can use this keyword to represent the current class in lambda expression while in the case of anonymous class this keyword represents that particular anonymous class.
  • In the case of Lambda expression, we need to provide the function body only while in the case of anonymous class we need to write the redundant class definition.

Advantages of Lambda Expression

Lambda Expressions allows us to code in functional style so it provides all benefits of functional style as well as above we can see Lambda Expressions lets developers
  • Simply understand the code.
  • Simplify and shorten their code.
  • Making it more readable and maintainable.
  • Remove more verbose class declarations.

Examples of Lambda Expressions

In below program, I have demonstrated different examples you can also found the source code on Github.

package org.programming.mitra.exercises;

import java.awt.Button;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.stream.IntStream;

public class LambdaExpression {

  @SuppressWarnings("unused")
  public static void main(String[] args) {

  // Example : Thread Creation
  // Old Way
  Runnable runnable = new Runnable() {
  @Override
  public void run() {
  System.out.println("Running thread using anonymous class");
  }
  };
  Thread thread = new Thread(runnable);
  thread.start();

  // New Way
  runnable = () -> System.out.println("Running thread using lambda expression");
  thread = new Thread(runnable);
  thread.start();

  // Example : Comparator Creation
  Comparator<Integer> comparator = (Integer i, Integer j) -> i.compareTo(j);

  // Example : Consumer Creation
  Consumer<String> consumer = obj -> System.out.println(obj);

  // Example : Consumer Creation
  Button button = new Button();

  // Old way:
  button.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent e) {
  System.out.println("button clicked");
  }
  });

  // New way:
  button.addActionListener((e) -> {
  System.out.println("button clicked");
  });

  // Example : Iteration
  System.out.println("####### Old way #######");
  for (int i = 1; i < 10; i++) {
  int j = i * i;
  System.out.println(j);
  }

  System.out.println("####### Lambda (Stream) way #######");
  IntStream.range(1, 10)
  .map(num -> num * num)
  .forEach(i -> System.out.println(i));

  }
}

Lambda expressions are heavily used in Java Stream API, which I am going to cover in later articles.
Whenever we install Java using JDK installer it creates two folders in installation directory one for JDK and one for JRE. However, JDK folder also contains one JRE folder itself and both have the same directory structure.

JDK Structure
JDK Structure

Let’s assume JDK is installed at \jdk1.7.0, below are some of the most important directories and their explanation
jdk1.7.0
    db
    include
    src.zip
    bin
         java*
         javac*
         javap*
         javah*
         javadoc*
    lib
         tools.jar
         dt.jar
    jre
         bin
              java*
         lib
              applet
              ext
                   jfxrt.jar
                   localdata.jar
              fonts
              security
              sparc
                   server
                   client
              rt.jar
              Charsets.jar


\jdk1.7.0 → This is the root directory of the JDK software installation which contains copyright, license, and readme files, src.zip and all other directories.


\jdk1.7.0\bin → Contains files for all executable tools which are necessary for Java program development . The PATH environment variable should contain an entry for this directory. Some of them are
  • appletviewer: Run and debug applets without a web browser.
  • extcheck: Utility to detect Jar conflicts.
  • jar: Create and manage Java Archive (JAR) files.
  • java: The launcher for Java applications.
  • javac: The compiler for the Java programming language.
  • javadoc: API documentation generator.
  • javah: C header and stub generator. Used to write native methods.
  • javap: Class file disassembler
  • jdb: The Java Debugger.


For more information on the tools, see the JDK Tools.


\jdk1.7.0\lib → Files used by the development tools, includes the following:
  • tools.jar: Contains non-core classes for support of the tools and utilities in the JDK.
  • dt.jar: DesignTime archive of BeanInfo files that tell interactive development environments (IDEs) how to display the Java components and how to let the developer customize them for an application.
  • ant-javafx.jar: Contains Ant tasks for packaging JavaFX applications; see Packaging in Deploying JavaFX Applications.
Other jars are jconsole.jar, packager.jar, sa-jdi.jar.


\jdk1.7.0\jre → Root directory of the Java runtime environment used by the JDK development tools. The runtime environment is an implementation of the Java platform. This is the directory represented by the java.home system property.


\jdk1.7.0\jre\bin → Contains executable files and DLLs for tools and libraries used by the Java platform. The executable files are identical to files in /jdk1.7.0/bin. The java launcher tool serves as an application launcher (and replaced the old jre tool that shipped with 1.1 versions of the JDK). This directory does not need to be in the PATH environment variable.


\jdk1.7.0\jre\bin\client → Contains the DLL files used by the Java HotSpot™ Client Virtual Machine.


\jdk1.7.0\jre\bin\server → Contains the DLL files used by the Java HotSpot™ Server Virtual Machine.


\jdk1.7.0\jre\lib → Code libraries, property settings, and resource files used by the Java runtime environment. For example:
  • rt.jar: Contains all Java platform's core API classes. These classes are loaded by Bootstrap Classloader.
  • charsets.jar: Character conversion classes
  • jfxrt.jar: JavaFX runtime libraries
Aside from the ext subdirectory (described below), there are several additional resource subdirectories not described here.


\jdk1.7.0\jre\lib\ext → Default installation directory for Extensions to the Java platform, Loaded by extension classloader.
  • localedata.jar: locale data for java.text and java.util.


\jdk1.7.0\jre\lib\security → Contains files used for security management. These include the security policy (java.policy) and security properties (java.security) files.


\jdk1.7.0\jre\lib\applet → Jar files containing support classes for applets can be placed in the lib/applet/ directory. This reduces startup time for large applets by allowing applet classes to be pre-loaded from the local file system by the applet class loader, providing the same protections as if they had been downloaded over the net.


\jdk1.7.0\jre\lib\fonts Contains TrueType font files for use by the platform.

There are some additional files and directories which are not required to a Java developer like below



\jdk1.7.0\src.zip → Archive containing source code for the Java platform.
\jdk1.7.0\db → Contains Java DB.
\jdk1.7.0\include → C language header files that support native-code programming using the Java Native Interface and the Java Virtual Machine Debugger Interface.

Reference: Java Documentation
According to Java standards and common practices, we should declare every class in its own source file. And even if we declare multiple classes in the single source file (.java) still each class will have its own class file after compilation. But the fact is that we can declare more than one class in a single source file with below constraints,
  • Each source file should contain only one public class and the name of that public class should be similar to the name of the source file.
  • If you are declaring the main method in your source file then main should lie in that public class

If there is no public class in the source file then main method can lie in any class and we can give any name to the source file.
If you are not following 1st constraint then you will receive a compilation error saying “The public type A must be defined in its own file”. While if you are not following the second constraint you will receive an error “Error: Could not find or load main class User” after the execution of the program and if you will try this in Eclipse then you will not get the option to execute the program.

Here we are talking about only top level classes, we can declare more than one public inner class.

Why only one public class per source file

Now we know that we can’t declare more than one public file in the single source file, Now we will look at why we can’t do this or why it is not allowed in Java.

Well, actually it is an optional restriction according to Java Language Specification (Section 7.6, Page No. 209) but followed by Oracle Java compiler as a mandatory restriction. According to Java Language Specification,

When packages are stored in a file system (§7.2.1), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:
  • The type is referred to by code in other compilation units of the package in which the type is declared.
  • The type is declared public (and therefore is potentially accessible from code in other packages).
This restriction implies that there must be at most one such type per compilation unit.
This restriction makes it easy for a Java compiler to find a named class within a package.
In practice, many programmers choose to put each class or interface type in its own compilation unit, whether or not it is public or is referred to by code in other compilation units.

For example, the source code for a public type wet.sprocket.Toad would be found in a file Toad.java in the directory wet/sprocket , and the corresponding object code would be found in the file Toad.class in the same directory.

Above clarification is a little bit typical to understand, So let’s replace the “type” word with actual a class Toad to get more clarification,

Java compiler may give an error if Toad class is not found in Toad.java and either of following is true
  • Toad class is referred in other classes in same package.
  • Toad class is declared public.
This restriction implies that there must be at most one such Toad class per compilation unit.
And the reason behind this is,
This restriction makes it easy for a compiler for the Java programming language or an implementation of the Java virtual machine to find a named class within a package.

To get more clear picture let's imagine there are two public classes public class A and public class B in the same source file and class A have reference to the not yet compiled class B. And we are compiling (compiling-linking-loading) class A now while linking to class B compiler will be forced to examine each *.java files within the current package because class B doesn’t have its specific B.java file. So In above case, it is a little bit time consuming for the compiler to find which class lies under which source file and in which class the main method lies.

So the reason behind keeping one public class per source file is to actually make compilation process faster because it enables a more efficient lookup of the source and compiled files during linking (import statements). The idea is if you know the name of a class, you know where it should be found for each classpath entry and no indexing will be required.

And also as soon as we execute our application JVM by default looks for the public class (since no restrictions and can be accessed from anywhere) and also looks for public static void main(String args[]) in that public class. Public class acts as the initial class from where the JVM instance for the Java application (program) is begun. So when we provide more than one public class in a program the compiler itself stops you by throwing an error. This is because later we can’t confuse the JVM as to which class to be its initial class because only one public class with the public static void main(String args[]) is the initial class for JVM.

But why can we declare more than one non-public class (default access) in a single source file

Although there is no particular specification or reference to point why it is allowed to have more than one non-public class per source file. Presumably, the point is that developers are more likely to want to find the source code for a public class than a non-public one because developers don’t work on the same package provided by others so they don’t need to know the non-public classes. So compiler should not worry too much about linking non-public class because these are private to package.

But we should declare every class in its own file because it we will make the source short, simple, well organised and easy to understand.

You can find the complete source code for my blog on this Github Repository and please feel free to provide your valuable feedback.
In Java, we generally create objects using the new keyword or we use some DI framework e.g. Spring to create an object which internally use Java Reflection API to do so. In this Article, we are going to study the reflective ways to create objects.

There are two methods present in Reflection API which we can use to create objects
  1. Class.newInstance() → Inside java.lang package
  2. Constructor.newInstance() → Inside java.lang.reflect package
However there are total 5 ways create objects in Java, if you are not aware of them please go through this article 5 Different ways to create objects in Java with Example.

Both Class.newInstance() and java.lang.reflect.Constructor.newInstance() are known as reflective methods because these two uses reflection API to create the object. Both are not static and we can call earlier one on a class level object while latter one needs constructor level object which we can get by using the class level object.

Class.newInstance()

The Class class is the most popular class in Java after the Object class. However, this class lies in the java.lang package but plays a major role in Reflection API (java.lang.reflect.* package).

In order to use Class.newInstance() we first need to get the class level instance of that class for which we want to create objects. We can do this by two ways one is writing complete name of the class and appending .class to it and another is using Class.forName() method, So in below code Employee.class is similar to (Employee) Class.forName("org.programming.mitra.exercises.Employee")

Below code demonstrates how we can create objects using Class.newInstance()
Employee emp = Employee.class.newInstance();

Or
Employee emp = (Employee) Class.forName("org.programming.mitra.exercises.Employee").newInstance();

Class.newInstance() internally itself use the Constructor.newInstance() to create the object as we can see in the source code of Class class, notice line no 430 and 442 in below image.

Creating objects through Reflection in Java with Example

Constructor.newInstance()

In order to use Constructor.newInstance() method we first need to get constructor object for that class and then we can call newInstance() on it to create objects as shown below

Constructor<Employee> constructor = Employee.class.getConstructor();
Employee emp3 = constructor.newInstance();

It internally use sun.reflect.ConstructorAccessor class to get the object, which is Oracle's private API.

Difference between Class.newInstance() and Constructor.newInstance()

By name, both methods look same but there are differences between them which we are as following

1. Class.newInstance() can only invoke the no-arg constructor,
        Constructor.newInstance() can invoke any constructor, regardless of the number of parameters.

2. Class.newInstance() requires that the constructor should be visible,
       Constructor.newInstance() can also invoke private constructors under certain circumstances.

3. Class.newInstance() throws any exception (checked or unchecked) thrown by the constructor,
        Constructor.newInstance() always wraps the thrown exception with an InvocationTargetException.

Due to above reasons Constructor.newInstance() is preferred over Class.newInstance(), that’s why used by various frameworks and APIs like Spring, Guava, Zookeeper, Jackson, Servlet etc.

You can find complete code on this Github Repository and please feel free to provide your valuable feedback.
While being a Java developer we usually create lots of objects daily, but we always use the new or dependency management systems e.g. Spring to create these objects. However, there are more ways to create objects which we are going to study in this article.

There are total 5 core ways to create objects in Java which are explained below with their example followed by bytecode of the line which is creating the object. However, lots of Apis are out there are which creates objects for us but these Apis will also are using one of these 5 core ways indirectly e.g. Spring BeanFactory.

5-different-ways-of-object-creation-in-Java-with-example-and-explanation

If you will execute program given in the end, you will see method 1, 2, 3 uses the constructor to create the object while 4, 5 doesn’t call the constructor to create the object.



1. Using the new keyword

It is the most common and regular way to create an object and actually very simple one also. By using this method we can call whichever constructor we want to call (no-arg constructor as well as parametrised).

 Employee emp1 = new Employee();
 0: new           #19              // class org/programming/mitra/exercises/Employee
 3: dup
 4: invokespecial #21              // Method org/programming/mitra/exercises/Employee."":()V


2. Using Class.newInstance() method

We can also use the newInstance() method of the Class class to create objects, This newInstance() method calls the no-arg constructor to create the object.
We can create objects by newInstance() in the following way.

Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee")
                               .newInstance();

Or

Employee emp2 = Employee.class.newInstance();
51: invokevirtual    #70    // Method java/lang/Class.newInstance:()Ljava/lang/Object;


3. Using newInstance() method of Constructor class

Similar to the newInstance() method of Class class, There is one newInstance() method in the java.lang.reflect.Constructor class which we can use to create objects. We can also call a parameterized constructor, and private constructor by using this newInstance() method.

Both newInstance() methods are known as reflective ways to create objects. In fact newInstance() method of Class class internally uses newInstance() method of Constructor class. That's why the later one is preferred and also used by different frameworks like Spring, Hibernate, Struts etc. To know the differences between both newInstance() methods read Creating objects through Reflection in Java with Example.

Constructor<Employee> constructor = Employee.class.getConstructor();
Employee emp3 = constructor.newInstance();
111: invokevirtual  #80  // Method java/lang/reflect/Constructor.newInstance:([Ljava/lang/Object;)Ljava/lang/Object;

4. Using clone() method

Whenever we call clone() on any object JVM actually creates a new object for us and copy all content of the previous object into it. Creating an object using the clone method does not invoke any constructor.

To use the clone() method on an object we need to implements Cloneable and define clone() method in it.

Employee emp4 = (Employee) emp3.clone();
162: invokevirtual #87  // Method org/programming/mitra/exercises/Employee.clone ()Ljava/lang/Object;

Java cloning is the most debatable topic in Java community and it surely does have its drawbacks but it is still the most popular and easy way of creating a copy of any object until that object is full filling mandatory conditions of Java cloning. I have covered cloning in details in a 3 article long  Java Cloning Series which includes articles like Java Cloning And Types Of Cloning (Shallow And Deep) In Details With ExampleJava Cloning - Copy Constructor Versus CloningJava Cloning - Even Copy Constructors Are Not Sufficient. Please go ahead and read them if you want to know more about cloning.

5. Using deserialization

Whenever we serialize and then deserialize an object JVM creates a separate object for us. In deserialization, JVM doesn’t use any constructor to create the object.
To deserialize an object we need to implement the Serializable interface in our class.

ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp5 = (Employee) in.readObject();
261: invokevirtual  #118   // Method java/io/ObjectInputStream.readObject:()Ljava/lang/Object;

As we can see in above bytecodes all 4 methods call get converted to invokevirtual (object creation is directly handled by these methods) except the first one which got converted to two calls one is new and other is invokespecial (call to the constructor).

I have discussed serialization and deserialization in more details in serialization series which includes articles like Everything You Need To Know About Java SerializationHow To Customize Serialization In Java By Using Externalizable InterfaceHow To Deep Clone An Object Using Java In Memory Serialization. Please go ahead and read them if you want to know more about serialization.

Example

Let’s consider an Employee class for which we are going to create the objects

class Employee implements Cloneable, Serializable {

    private static final long serialVersionUID = 1L;

    private String name;

    public Employee() {
        System.out.println("Employee Constructor Called...");
    }

    public String getName() {
        return name;
    }

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

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Employee [name=" + name + "]";
    }

    @Override
    public Object clone() {

        Object obj = null;
        try {
            obj = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return obj;
    }
}

In below Java program, we are going to create Employee objects in all 5 ways, you can also found the complete source code at Github.

public class ObjectCreation {
    public static void main(String... args) throws Exception {

        // By using new keyword
        Employee emp1 = new Employee();
        emp1.setName("Naresh");

        System.out.println(emp1 + ", hashcode : " + emp1.hashCode());


        // By using Class class's newInstance() method
        Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee")
                               .newInstance();

        // Or we can simply do this
        // Employee emp2 = Employee.class.newInstance();

        emp2.setName("Rishi");

        System.out.println(emp2 + ", hashcode : " + emp2.hashCode());


        // By using Constructor class's newInstance() method
        Constructor<Employee> constructor = Employee.class.getConstructor();
        Employee emp3 = constructor.newInstance();
        emp3.setName("Yogesh");

        System.out.println(emp3 + ", hashcode : " + emp3.hashCode());

        // By using clone() method
        Employee emp4 = (Employee) emp3.clone();
        emp4.setName("Atul");

        System.out.println(emp4 + ", hashcode : " + emp4.hashCode());


        // By using Deserialization

        // Serialization
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"));

        out.writeObject(emp4);
        out.close();

        //Deserialization
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
        Employee emp5 = (Employee) in.readObject();
        in.close();

        emp5.setName("Akash");
        System.out.println(emp5 + ", hashcode : " + emp5.hashCode());

    }
}

This program will give the following output

Employee Constructor Called...
Employee [name=Naresh], hashcode : -1968815046
Employee Constructor Called...
Employee [name=Rishi], hashcode : 78970652
Employee Constructor Called...
Employee [name=Yogesh], hashcode : -1641292792
Employee [name=Atul], hashcode : 2051657
Employee [name=Akash], hashcode : 63313419
Next Post Newer Posts Previous Post Older Posts Home