Java - How Class is loaded and initialized

来源:互联网 发布:淘宝消保30元加入条件 编辑:程序博客网 时间:2024/06/05 11:25

http://javarevisited.blogspot.de/2012/12/how-classloader-works-in-java.html

http://javarevisited.blogspot.sg/2012/07/when-class-loading-initialization-java-example.html

Sometimes I can't open this page without proper proxy, so I have to copy the content here.


What is ClassLoader in Java

ClassLoader in Java is a class which is used to load class files at runtime in Java. Java code is compiled into class file by javac compiler and JVM executes Java program, by executing byte codes written in class file. ClassLoader is responsible for loading class files from file system, network or any other source.

There are three default class loader used in Java, Bootstrap , Extension and System or Application class loader. Every class loader has a predefined location, from where they loads class files.

Bootstrap ClassLoader is responsible for loading standard JDK class files from JRE/lib/rt.jar. it is parent of all class loaders in Java. Bootstrap class loader don't have any parents, if you call String.class.getClassLoader() it will return null and any code based on that may throw NullPointerException in Java. Bootstrap class loader is also known as Primordial ClassLoader in Java.

Extension ClassLoader delegates class loading request to its parent, Bootstrap and if unsuccessful, loads class form jre/lib/ext directory or any other directory pointed by java.ext.dirs system property. Extension ClassLoader in JVM is implemented by  sun.misc.Launcher$ExtClassLoader.

Third default class loader used by JVM to load Java classes is called System or Application class loader and it is responsible for loading application specific classes from CLASSPATH environment variable, -classpath or -cp command line option, Class-Path attribute of Manifest file inside JAR. Application class loader is a child of Extension ClassLoader and its implemented by sun.misc.Launcher$AppClassLoader class.
Remember Classpath is used to load class files while PATH is used to locate executable like javac or java command.

except Bootstrap class loader, which is implemented in native language mostly in C,  all  Java class loaders are implemented using java.lang.ClassLoader.

How ClassLoader works in Java

ClassLoader in Java works on three principle: delegation, visibility and uniqueness.

Delegation principle forward request of class loading to parent class loader and only loads the class, if parent is not able to find or load class.

Visibility principle allows child class loader to see all the classes loaded by parent ClassLoader, but parent class loader can not see classes loaded by child.

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.

How to load class explicitly in Java

Java provides API to explicitly load a class by Class.forName(classname) and Class.forName(classname, initialized, classloader). Class is loaded by calling loadClass() method of java.lang.ClassLoader class which calls findClass() method to locate bytecodes for corresponding class.

<Class_name>.class.getClassLoader() 可以得到 load 这个class的 ClassLoader。

Where to use ClassLoader in Java

ClassLoader in Java is a powerful concept and used at many places. One of the popular example of ClassLoader is AppletClassLoader which is used to load class by Applet, since Applets are mostly loaded from internet rather than local file system, By using separate ClassLoader you can also loads same class from multiple sources and they will be treated as different class in JVM. J2EE uses multiple class loaders to load class from different location like classes from WAR file will be loaded by Web-app ClassLoader while classes bundled in EJB-JAR is loaded by another class loader. Some web server also supports hot deploy functionality which is implemented using ClassLoader. You can also use ClassLoader to load classes from database or any other persistent store.

When Class is loaded in Java

Class loading is done by ClassLoaders in Java which can be implemented to eagerly load a class as soon as another class references it or lazy load the class until a need of class initialization occurs. If Class is loaded before it's actually being used it can sit inside before being initialized. Its guaranteed by JLS that a class will be loaded when there is a need of static initialization.

When a Class is initialized in Java

After class loading, initialization of class takes place which means initializing all static members of class. A Class is initialized in Java when :

1) an Instance of class is created either using new() keyword or using reflection using class.forName()
2) an static method of Class is invoked.
3) an static field of Class is assigned.
4) an static field of class is used which is not a constant variable.
5) if Class is a top level class and an assert statement lexically nested within class is executed.

How Class is initialized in Java

It's important to know in which order various fields (static and non static), block (static and non static), various classes (sub class and super class) and various interfaces (sub interface, implementation class and super interface) is initialized in Java.

Here are some of the rules of class initialization in Java:

1) Classes are initialized from top to bottom so field declared on top initialized before field declared in bottom
2) Super Class is initialized before Sub Class or derived class in Java
3) If Class initialization is triggered due to access of static field, only Class which has declared static field is initialized and it doesn't trigger initialization of super class or sub class even if static field is referenced by Type  of Sub Class, Sub Interface or by implementation class of interface.
4) interface initialization in Java doesn't cause super interfaces to be initialized.
5) static fields are initialized during static initialization of class while non static fields are initialized when instance of class is created. It means static fields are initialized before non static fields in Java.
6)non static fields are initialized by constructors in Java. sub class constructor implicitly call super class constructor before doing any initialization, which guarantees that non static or instance variables of super class is initialized before sub class.

Examples of  class initialization in Java:
Here is an example of when class is initialized in Java. In this example we will see which classes are initialized in Java.

/** * Java program to demonstrate class loading and initialization in Java. */public class ClassInitializationTest {    public static void main(String args[]) throws InterruptedException {         NotUsed o = null; //this class is not used, should not be initialized        Child t = new Child(); //initializing sub class, should trigger super class initialization        System.out.println((Object)o == (Object)t);    }}/** * Super class to demonstrate that Super class is loaded and initialized before Subclass. */class Parent {    static { System.out.println("static block of Super class is initialized"); }    {System.out.println("non static blocks in super class is initialized");}}/** * Java class which is not used in this program, consequently not loaded by JVM */class NotUsed {    static { System.out.println("NotUsed Class is initialized "); }}/** * Sub class of Parent, demonstrate when exactly sub class loading and initialization occurs. */class Child extends Parent {    static { System.out.println("static block of Sub class is initialized in Java "); }    {System.out.println("non static blocks in sub class is initialized");}}Output:static block of Super class is initializedstatic block of Sub class is initialized in Javanon static blocks in super class is initializednon static blocks in sub class is initializedfalse

Let's have a look on another example of class initialization in Java:

/** * Another Java program example to demonstrate class initialization and loading in Java. */public class ClassInitializationTest {    public static void main(String args[]) throws InterruptedException {        //accessing static field of Parent through child, should only initialize Parent       System.out.println(Child.familyName);    }}class Parent {    //compile time constant, accessing this will not trigger class initialization    //protected static final String familyName = "Lawson";     protected static String familyName = "Lawson";     static { System.out.println("static block of Super class is initialized"); }    {System.out.println("non static blocks in super class is initialized");}}Output:static block of Super class is initializedLawson


Observation

1. Here class initialization occurs because static field is accessed which is not a compile time constant. had you declare "familyName" compile time constant using final keyword in Java (as shown in commented section) class initialization of super class would not have occurred.

2. Only super class is initialized even though static field is referenced using sub type.


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 12306的登录密码忘了怎么办 网银支付密码忘了怎么办 邮政网银密码忘了怎么办 12306新注册待核验怎么办 建行网银盾密码忘了怎么办 建行网银登陆密码忘了怎么办 建行网银密码忘了怎么办 建行手机网银密码忘了怎么办 移动宽带账号密码忘了怎么办 移动宽带忘记账号密码怎么办 宽带账号密码忘了怎么办 不知道宽带账号密码怎么办 宽带的账号密码忘记了怎么办 wifi登录名忘记了怎么办 苹果手机微信图纸打不开怎么办 手机qq邮箱文件打不开怎么办 12360忘记用户名和密码怎么办 刚开店铺没生意怎么办 淘宝账户不符合注销条件怎么办 网易邮箱登录密码忘记了怎么办 q号密码忘记了怎么办 志愿者注册忘记密码和用户名怎么办 w10电脑语言栏不见了怎么办 w10美式键盘没了怎么办 xp电脑开机密码忘记了怎么办 电脑开机密码到期忘记改怎么办 电脑账户数据库密码忘了怎么办 微信不能拍摄了怎么办 华硕笔记本用户名密码忘了怎么办 学信网登录密码用户名搞忘怎么办 电脑密码输入错误会被锁怎么办 电脑被锁机软件设了密码怎么办 电脑密码被锁了怎么办 电脑xp密码忘了怎么办 三星账户账号密码忘了怎么办 三星账户密码忘记了怎么办 w7账号被禁用了怎么办 笔记本用户名密码忘记了怎么办 笔记本忘记用户名和密码怎么办 苹果手机忘记用户名和密码怎么办 w10电脑忘了密码怎么办