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 → 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 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 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 a same source file and A class 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 don’t have it’s 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 accessible 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.

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.


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();

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


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.


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")


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, 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 my article Everything About Java Serialization Explained With Example, please go ahead and read it if you want to know more about it.


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;

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

    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;

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

    public Object clone() {

        Object obj = null;
        try {
            obj = super.clone();
        } catch (CloneNotSupportedException e) {
        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();

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

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

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


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

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

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

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

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

        // By using Deserialization

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


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

        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
Plain Old Java Object or POJO is just an ordinary Java object, The term was originally coined by Martin Fowler, Rebecca Parsons, and Josh Mackenzie in September 2000.

According to Martin Fowler

The term was coined while Rebecca Parsons, Josh MacKenzie and I were preparing for a talk at a conference in September 2000. In the talk we were pointing out the many benefits of encoding business logic into regular java objects rather than using Entity Beans. We wondered why people were so against using regular objects in their systems and concluded that it was because simple objects lacked a fancy name. So we gave them one, and it’s caught on very nicely.

Generally, a POJO is not bound to any restriction and any Java object can be called a POJO but there are some directions. A well-defined POJO should follow below directions.
  1. Each variable in a POJO should be declared as private.
  2.     private long id;
        private String value = "";
        private Collection<Term> children = Collections.emptyList();

  3. Default constructor should be overridden with public accessibility.
  4.     public Term() {

  5. Each variable should have its Setter-Getter method with public accessibility.
  6.     public long getId() {
            return id;
        public void setId(long id) {
            this.id = id;
        public String getValue() {
            return value;
        public void setValue(String value) {
            this.value = value;
        public Collection<Term> getChildren() {
            return children;
        public void setChildren(Collection<Term> children) {
            this.children = children;
  7. Generally POJO should override equals(), hashCode() and toString() methods of Object (but it's not mandatory).

  8. Overriding these methods will help us while using our POJO with different Java collection classes or writing it directly to console or inspecting it in debugger.

        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((value == null) ? 0 : value.hashCode());
            result = prime * result + ((children == null) ? 0 : children.hashCode());
            return result;
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Term other = (Term) obj;
            if (value == null) {
                if (other.value != null)
                    return false;
            } else if (!value.equals(other.value))
                return false;
            if (children == null) {
                if (other.children != null)
                    return false;
            } else if (!children.equals(other.children))
                return false;
            return true;
        public String toString() {
            return "Term [id=" + id + ", value=" + value + ", children=" + children + "]";

  9. Overriding compare() method of Comparable interface used for sorting (Preferable but not mandatory).
  10.     @Override
        public int compareTo(Term term) {
            return (int) (this.id - term.id);

And according to Java Language Specification, a POJO should not have to
  1. Extend prespecified classes, as in
  2.     public class Foo extends javax.servlet.http.HttpServlet {

  3. Implement prespecified interfaces, as in
  4.     public class Bar implements javax.ejb.EntityBean {

  5. Contain prespecified annotations, as in
  6.     @javax.persistence.Entity 
        public class Baz {

However, developers and frameworks describe a POJO still requires the use prespecified annotations to implement features like persistence, declarative transaction management etc. So the idea is that if the object was a POJO before any annotations were added would return to POJO status if the annotations are removed then it can still be considered a POJO.
A JavaBean is a special kind of POJO that is Serializable, has a no-argument constructor, and allows access to properties using getter and setter methods that follow a simple naming convention.
As being a Java programmer we all know what is a reference, But let’s go through this again which it will help us to understand our current topic which is “Types of References in Java”.

All types in Java lies under two categories
  1. Primitive Types: There are 8 primitive types (byte, short, int, long, float, double, char and boolean) in Java which holds their values directly in form of bits. 
  2. Reference Types: All types other than primitive lies under the category of reference types e.g. Classes, Interfaces, Enums, Arrays etc. 
We can define a reference similar as primitive as

Employee emp = new Employee();

Here “new Employee()” is actually the object which gets space in heap, and “emp” is called reference variable which is holding the object, holding means “emp” variable stores the address of the object in form of bits.

As long as “emp” is holding this object it is not eligible for garbage collection. Because it is still in use and is reachable from “emp” reference.

Now if we assign a new object to “emp” it will hold the address of the new object and because now nobody is holding the reference of that old employee object it will become eligible for garbage collection.

Based on the behavior of references with Garbage Collector we can divide references into 4 sections given below in order from strongest to weakest.
  1. Strong References
  2. Soft References
  3. Weak References
  4. Phantom References

Strong References

These are your regular object references which we code daily:

Employee emp = new Employee();

The variable “emp” holds a strong reference to an Employee object and objects that are reachable through any chain of strong references are not eligible for garbage collection.
Usually, this is what you want but not always. Now suppose we are fetching lots of employees from database in a collection or map, and we need to do a lot of processing on them regularly, So in order keep performance we will keep them in the cache.

As far as this is good but now we need different data and we don’t need those Employee objects and these are not referenced from anywhere except the cache. Which is causing a memory leak because these objects are not in use but still not eligible for the garbage collection and we cannot remove those objects from cache because we don’t have reference to them?
So here either we need to empty the entire cache manually which is tedious or we could use other kind references e.g. Weak References.

Weak References

A weak reference does not pin an object into memory and will be GC’d in next GC cycle if not referenced from other references. We can use WeakReference class which is provided by Java to create above kind of caches, which will not store objects which are not referenced from somewhere else.

WeakReference<Cache> cache = new WeakReference<Cache>(data);

To access data you need to call cache.get(). This call to get may return null if the weak reference was garbage collected: you must check the returned value to avoid NPEs.
Java provides collections that use weak references e.g., the WeakHashMap class stores keys (not values) as weak references. If the key is GC’d then the value will automatically be removed from the map too.

Since weak references are objects too we need a way to clean them up (they’re no longer useful when the object they were referencing has been GC’d). If you pass a ReferenceQueue into the constructor for a weak reference then the garbage collector will append that weak reference to the ReferenceQueue before they’re finalized or GC’d. You can periodically process this queue and deal with dead references.

Soft References

A SoftReference is like a WeakReference but it is less likely to be garbage collected. Soft references are cleared at the discretion of the garbage collector in response to memory demand. The virtual machine guarantees that all soft references to softly reachable objects will have been cleared before it would ever throw an OutOfMemoryError.

Phantom References

Phantom references are the weakest of all reference types, calling get on them will always return null. An object is phantomly referenced after it has been finalized, but before its allocated memory has been reclaimed, As opposed to weak references which are enqueued before they’re finalized or GC’d Phantom references are rarely used.

So how are they useful? When you construct a phantom reference you must always pass in a ReferenceQueue. This indicates that you can use a phantom reference to see when your object is GC’d.

Hey, so if weak references are enqueued when they’re considered finalize but not yet GC’d we could create a new strong reference to the object in the finalizer block and prevent the object being GC’d. Yep, you can but you probably shouldn’t do this. To check for this case the GC cycle will happen at least twice for each object unless that object is reachable only by a phantom reference. This is why you can run out of heap even when your memory contains plenty of garbage. Phantom references can prevent this.
Next Post Newer Posts Previous Post Older Posts Home