ClassLoader in Java

Last Updated : 7 Jan 2026

Java ClassLoader

Java ClassLoader is an abstract class. It belongs to a java.lang package. It loads classes from different resources. Java ClassLoader is used to load the classes at run time. In other words, JVM performs the linking process at runtime. Classes are loaded into the JVM according to need. If a loaded class depends on another class, that class is loaded as well. When we request to load a class, it delegates the class to its parent. In this way, uniqueness is maintained in the runtime environment. It is essential to execute a Java program.

ClassLoader in Java

Java ClassLoader is based on three principles: Delegation, Visibility, and Uniqueness.

  • Delegation Principle: It forwards the request for class loading to parent class loader. It only loads the class if the parent does not find or load the class.
  • Visibility Principle: It allows child class loader to see all the classes loaded by parent ClassLoader. But the parent class loader cannot see classes loaded by the child class loader.
  • Uniqueness Principle: It allows to load a class once. It is achieved by delegation principle. It ensures that child ClassLoader does not reload the class, which is already loaded by the parent.

Types of ClassLoader

In Java, every ClassLoader has a predefined location from where they load class files. There are following types of ClassLoader in Java:

Bootstrap Class Loader: It loads standard JDK class files from rt.jar and other core classes. It is a parent of all class loaders. It does not have any parent. When we call String.class.getClassLoader() it returns null, and any code based on it throws NullPointerException. It is also called Primordial ClassLoader. It loads class files from jre/lib/rt.jar. For example, java.lang package class.

Extensions Class Loader: It delegates class loading request to its parent. If the loading of a class is unsuccessful, it loads classes from jre/lib/ext directory or any other directory as java.ext.dirs. It is implemented by sun.misc.Launcher$ExtClassLoader in JVM.

System Class Loader: It loads application specific classes from the CLASSPATH environment variable. It can be set while invoking program using -cp or classpath command line options. It is a child of Extension ClassLoader. It is implemented by sun.misc.Launcher$AppClassLoader class. All Java ClassLoader implements java.lang.ClassLoader.

ClassLoader in Java

How ClassLoader works in Java?

When JVM request for a class, it invokes java.lang.ClassLoader.loadClass() method by passing the fully classified name of the class. The ClassLoader.loadClass() method calls for findLoadedClass() method to check that the class has been already loaded or not. It is required to avoid loading the class multiple times.

If the class is already loaded, it delegates the request to parent ClassLoader to load the class. If the ClassLoader is not finding the class, it invokes the findClass() method to look for the classes in the file system. The following diagram shows how ClassLoader loads class in Java using delegation.

ClassLoader in Java

Suppose, we have an application specific class Main.class. The request for loading of this class files transfers to Application ClassLoader. It delegates to its parent Extension ClassLoader. Further, it delegates to Bootstrap ClassLoader. Bootstrap search that class in rt.jar and since that class is not there. Now request transfer to Extension ClassLoader which searches for the directory jre/lib/ext and tries to locate this class there. If the class is found there, Extension ClassLoader loads that class. Application ClassLoader never loads that class. When the extension ClassLoader does not load it, then Application ClaasLoader loads it from CLASSPATH in Java.

Visibility principle states that child ClassLoader can see the class loaded by the parent ClassLoader, but vice versa is not true. It means if Application ClassLoader loads Main.class, in such case, trying to load Main.class explicitly using Extension ClassLoader throws java.lang.ClassNotFoundException.

According to the uniqueness principle, a class loaded by the parent should not be loaded by Child ClassLoader again. So, it is possible to write class loader which violates delegation and uniqueness principles and loads class by itself.

In short, class loader follows the rules given below:

  • It checks if the class is already loaded.
  • If the class is 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.

Example: ClassLoader

Compile and Run

Output:

How are you?

Compile and run the above code by using the following command:

-verbose:class: It is used to display the information about classes being loaded by JVM. It is useful when using class loader for loading classes dynamically. The following figure shows the output.

ClassLoader in Java

We can observe that runtime classes required by the application class (Main) are loaded first.

When classes are loaded?

There are only two cases:

  • When the new byte code is executed.
  • When the byte code makes a static reference to a class. For example, System.out.

Static Vs. Dynamic Class Loading

Classes are statically loaded with "new" operator. Dynamic class loading invokes the functions of a class loader at run time by using Class.forName() method.

Difference Between ClassLoader.loadClass() and Class.forName()

The ClassLoader.loadClass() method loads only the class but does not initialize the object. While Class.forName() method initialize the object after loading it. For example, if you are using ClassLoader.loadClass() to load the JDBC driver, class loader does not allow to load JDBC driver.

The java.lang.Class.forName() method returns the Class Object coupled with the class or interfaces with the given string name. It throws ClassNotFoundException if the class is not found.

Example

In this example, java.lang.String class is loaded. It prints the class name, package name, and the names of all available methods of String class. We are using Class.forName() in the following example.

Class<?>: Represents a Class object which can be of any type (? is a wildcard). The Class type contains meta-information about a class. For example, type of String.class is Class<String>. Use Class<?> if the class being modeled is unknown.

getDeclaredMethod(): Returns an array containing Method objects reflecting all the declared methods of the class or interface represented by this Class object, including public, protected, default (package) access, and private methods, but excluding inherited methods.

getName(): It returns the method name represented by this Method object, as a String.

Example

Compile and Run

Output:

Class Name: java.lang.String
Package Name: package java.lang
-----Methods of String Class -------------
value
equals
length
toString
checkIndex
hashCode
getChars
compareTo
compareTo
indexOf
indexOf
indexOf
indexOf
indexOf
indexOf
indexOf
valueOf
valueOf
valueOf
valueOf
valueOf
valueOf
valueOf
valueOf
valueOf
coder
rangeCheck
checkBoundsOffCount
lookupCharset
decode2
decodeUTF8_UTF16
scale
decodeWithDecoder
newStringNoRepl1
newStringUTF8NoRepl
throwMalformed
throwMalformed
encodeUTF8
encode8859_1
encode8859_1
encodeASCII
encodeWithEncoder
trimArray
encode
getBytesNoRepl1
isASCII
throwUnmappable
throwUnmappable
replaceNegatives
isNotContinuation
isMalformed3
malformed3
decode3
isMalformed3_2
decode4
isMalformed4
malformed4
isMalformed4_2
isMalformed4_3
encodeUTF8_UTF16
computeSizeUTF8_UTF16
isLatin1
charAt
codePointAt
codePointBefore
codePointCount
offsetByCodePoints
checkBoundsBeginEnd
getBytes
getBytes
getBytes
getBytes
getBytes
getBytes
contentEquals
contentEquals
nonSyncContentEquals
regionMatches
regionMatches
startsWith
startsWith
lastIndexOf
lastIndexOf
lastIndexOf
lastIndexOf
lastIndexOf
substring
substring
isEmpty
replace
replace
matches
replaceFirst
replaceAll
split
split
split
split
splitWithDelimiters
join
join
join
toLowerCase
toLowerCase
toUpperCase
toUpperCase
trim
strip
stripLeading
stripTrailing
indexOfNonWhitespace
lines
repeat
lastIndexOfNonWhitespace
outdent
isBlank
toCharArray
format
format
repeatCopyRest
resolveConstantDesc
resolveConstantDesc
codePoints
newStringNoRepl
getBytesUTF8NoRepl
getBytesNoRepl
decodeASCII
bytesCompatible
copyToSegmentRaw
equalsIgnoreCase
compareToIgnoreCase
endsWith
subSequence
concat
contains
indent
stripIndent
translateEscapes
chars
transform
formatted
copyValueOf
copyValueOf
intern
checkOffset
valueOfCodePoint
describeConstable
lambda$stripIndent$0
lambda$indent$2
lambda$indent$1
lambda$indent$0

Applications of ClassLoader

  • Web Servers and Application Containers (Tomcat, JBoss) use ClassLoaders to load and reload web applications dynamically.
  • JDBC Drivers use ClassLoaders to load database drivers at runtime (Class.forName("com.mysql.jdbc.Driver")).
  • Frameworks like Spring and Hibernate use reflection and ClassLoaders for dependency injection and proxy creation.
  • Plugins and Modular Applications (like Eclipse, IntelliJ IDEA) use custom ClassLoaders for loading external plugins.

Conclusion

Java ClassLoaders act as fundamental runtime components because they apply dynamic class loading together with efficient memory management practices. Java application robustness in enterprise and modular environments requires full comprehension of how ClassLoaders function with their parent delegation framework and capability to create custom ClassLoaders.

The application performance improves when developers understand ClassLoaders which enables them to resolve class-loading problems while taking advantage of Java's dynamic runtime capabilities.


Next TopicJava Tutorial