All class files in
application are not loaded into memory at startup, but are loaded on demand as
needed by the program, this loading of class is done by ClassLoader.
ClassLoader is a part of JVM that loads classes into memory.
ClassLoader in Java works on
three principle:
Delegation - Delegation principle forward class loading request
to parent class loader and only loads the class, if parent is not able to find
or load class.
Visibility - Visibility principle allows child class loader
to see all the classes loaded by parent ClassLoader, but parent class loader cannot
see.
Uniqueness - Uniqueness principle allows to load a class
exactly once, which is basically achieved by delegation and ensures that child
ClassLoader doesn't reload the class already loaded by parent.
Type of
ClassLoader –
There are three default class
loader used in Java.
1.
Bootstrap – Bootstrap class loader loads the core java
library located in the (<JAVA_HOME>/jre/lib). It is a Super class loader.
It loads the Core classes of Java like class in java.lang, java.util package.
2. Extension
– Extension class loader loads
the code in the extension directories (<JAVA_HOME>jre/lib/ext) or any
other directory specified by the (java.ext.dirs) system property. It implements
by the sun.misc.Launcher$ExtClassLoader class
3. System
or Application class loader – The system class loader loads the code found on
java.class.path which maps to the classpath environment variable. This is
implemented by the sun.misc.Launcher$AppClassLoader
Develoeper can also create Custom class
according to their need.
See below code snippet for
custom class loader:
public class ClassLoaderTest {
public static void main(String[] args) {
Thread thread = Thread.currentThread();
ClassLoader classLoader = thread.getContextClassLoader();
try {
ClassLoaderImpl classLoaderImpl = new ClassLoaderImpl();
thread.setContextClassLoader(classLoaderImpl);
System.out.println("Loaded class context is
"+thread.getContextClassLoader());
} finally {
thread.setContextClassLoader(classLoader);
}
System.out.println("Loaded class context is "+thread.getContextClassLoader());
}
}
class ClassLoaderImpl extends ClassLoader {
public ClassLoaderImpl() {
super();
}
/*
* custom code for class loader
*/
}
package com.mk.test.basics;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
public class TestMain {
public static void main(String[] args) throws Exception {
CustomClassLoader loader = new CustomClassLoader();
Class<?> classObj = loader.findClass("com.mk.test.basics.TestMain");
Object object = classObj.newInstance();
Method method = classObj.getMethod("hello");
method.invoke(object);
}
public void hello(){
System.out.println("Hello MK Study Journal!");
}
}
class CustomClassLoader extends ClassLoader{
public Class<?> findClass(String classPath) {
byte[] bytes = loadClassData(classPath);
return defineClass(classPath, bytes, 0, bytes.length);
}
private byte[] loadClassData(String className) {
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(className.replace(".", "/")+".class");
byte byteArray[] = null;
try {
byteArray = new byte[inputStream.available()];
DataInputStream dataStream = new DataInputStream(inputStream);
dataStream.readFully(byteArray);
dataStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return byteArray;
}
}
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
public class TestMain {
public static void main(String[] args) throws Exception {
CustomClassLoader loader = new CustomClassLoader();
Class<?> classObj = loader.findClass("com.mk.test.basics.TestMain");
Object object = classObj.newInstance();
Method method = classObj.getMethod("hello");
method.invoke(object);
}
public void hello(){
System.out.println("Hello MK Study Journal!");
}
}
class CustomClassLoader extends ClassLoader{
public Class<?> findClass(String classPath) {
byte[] bytes = loadClassData(classPath);
return defineClass(classPath, bytes, 0, bytes.length);
}
private byte[] loadClassData(String className) {
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(className.replace(".", "/")+".class");
byte byteArray[] = null;
try {
byteArray = new byte[inputStream.available()];
DataInputStream dataStream = new DataInputStream(inputStream);
dataStream.readFully(byteArray);
dataStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return byteArray;
}
}
Great collection, very usefull thanks
ReplyDelete