This article explains the key components of Java class loaders.
Java Class Loaders are essential part of Java Virtual Machine (JVM). They are used to load classes and interfaces. Althaout class loaders are integral part of JVM and they are very important for the internal working of Java it is unlikely you will need to create a custom class loader in your everyday work as a java developer. Real-life application of custom class loader is for example if you want to create application that will be executed on a container such as Tomcat. What Tomcat does is create a class loader for each web application (so that it can unload the webapps later and release memory).
This article is written with the attempt to explain how class loaders work and to list the key components of a Java Class Loaders. You may encounter questions about class loaders on your next Java job interview.
What is Java ClassLoader
We know that Java programs run on Java Virtual Machine (JVM). When we compile a Java Class, it transforms into bytecode that is platform and machine independent. Compiled classes are stored as a .class file. When we try to use a Class, Java ClassLoader loads that class into memory. Classes are introduced into the Java environment when they are referenced by name in a class that is already running. Future attempts at loading classes are done by the class loader, once the first class is running. Running the first class is usually done by declaring and using a static main() method.
Types of Java Class Loaders
- Bootstrap Class Loader – It loads JDK internal classes, typically loads rt.jar and other core classes for example java.lang.* package classes
- Extensions Class Loader – It loads classes from the JDK extensions directory, usually lib/ext directory of the JRE.
- System Class Loader –Loads classes from system classpath, that can be set while invoking a program using -cp or -classpath command line options.
When and How are Classes Loaded
When classes are loaded? There are exactly two cases:
- when the new bytecode is executed (for example, MyClass mc = new MyClass()😉
- when the bytecodes make a static reference to a class (for example, System.out).
Class loaders are hierarchical. The very first class is specially loaded with the help of static main() method declared in your class. All the subsequently loaded classes are loaded by the classes, which are already loaded and running.
Further classloaders follow this rules when loading classes:
- Check if the class was already loaded.
- If not loaded, ask parent class loader to load the class.
- If parent class loader cannot load class, attempt to load it in this class loader.
Static vs. Dynamic class loading
Classes are statically loaded with Java’s “new” operator. Dynamic loading is a technique for programmatically invoking the functions of a class loader at run-time by using Class.forName()
Difference between loadClass and Class.forName
loadClass only loads the class but doesn’t initialize the object whereas Class.forName initialize the object after loading it. For example, if you use ClassLoader.loadClass to load a JDBC driver, it won’t get registered, and you won’t be able to use JDBC
The java.lang.Class.forName(String className) method returns the Class object associated with the class or interface with the given string name. This method throws ClassNotFoundException if the class is not found
Following example demonstrates the usage of Class.forName
package net.javatutorial; import java.lang.reflect.Method; public class ClassForNameExample { public static void main(String[] args) { try { Class<?> c = Class.forName("java.awt.Point"); System.out.println("name = " + c.getName()); System.out.println("package = " + c.getPackage()); Method[] methods = c.getDeclaredMethods(); System.out.println("----- Class methods ---------------"); for (Method method : methods) { System.out.println(method.getName()); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
java.awt.Point class is loaded. Than we print the class name, the package and the names of all available methods of this class. This is the result of executing the program in Java 8:
name = java.awt.Point package = package java.awt, Java Platform API Specification, version 1.8 ----- Class methods --------------- equals toString getLocation getX getY setLocation setLocation setLocation move translate
It’s not clear what a parent class loader is. You refer at the *hierarchical* organization of class loader, but maybe you could be more detailed explaining it.