版权声明:转载请标明来源 https://blog.csdn.net/u010652576/article/details/78449893
class文件的加载包含以下过程:加载(load class文件)-校验-准备-解析-初始化-实例化,上述过程是大致过程,具体过程可以参考:jvm class文件加载过程。
看下面的代码样例:
package staticclass;
public class StaticClassTest {
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader.getSystemClassLoader().loadClass("staticclass.User");
System.out.println("=====");
Class.forName("staticclass.User");
System.out.println("+++++");
}
}
//展示class文件的加载
class User{
public static int age=27;
private String name;
static{
System.out.println("this is static age="+age);
}
{
System.out.println(" age ="+age);
}
public User(String name){
System.out.println("this is constructor age="+age);
this.name=name;
}
public void print(){
System.out.println("this is "+name);
}
public static void printAge(){
System.out.println("this is static printAge age="+age);
}
}
输出内容:
=====
this is static age=27
+++++
从输出内容看到:ClasLoader把class文件进行加载,只是把相关的class文件加载到了方法区,进行了解析,并没有进行初始化,而Class.forName除了上述步骤执行了相关的初始化。
把StaticClassTest 的main方法修改如下:
public static void main(String[] args) throws ClassNotFoundException {
Class.forName("staticclass.User");
System.out.println("+++++");
User u = new User("jkf");
}
输出内容:
this is static age=27
+++++
age =27
this is constructor age=27
从输出内容来看:Class.forName进行了初始化,而new User进行了实例化,但是static代码块,仅执行了一次,并且代码块的执行优先构造函数。
把StaticClassTest 的main方法修改如下:
public static void main(String[] args) throws ClassNotFoundException {
int age = User.age;
System.out.println("----------");
User u = new User("jkf");
}
输出内容:
this is static age=27
----------
age =27
this is constructor age=27
从输出内容看:当我们调用类的静态属性或者方法时,仅进行了类的初始化,并不会进行实例化。
综上所述:
1 class文件的加载可以通过:ClassLoader进行加载。
2 class文件的初始化:Class.forName;调用类文件的静态方法或静态属性。
3 class文件的实例化:通过new;或者通过Class对象的newInstance()方法。
4 当然class文件的初始化包含了class文件的加载,同样class文件的实例化也包含上述两个步骤。
5 说一个有关数组的问题:
package com.classLoader;
/**class对象的加载时机**/
public class ClassLoaderTime {
public static void main(String[] args) {
ClassLoader[] arr = new ClassLoader[4];
System.out.println("数组赋值");
arr[0]=new ClassLoader();
}
}
class ClassLoader{
static{
System.out.println("对象初始化");
}
}
输出内容:
数组赋值
对象初始化
从输出内容来看,对象数组创建时,并没有加载初始化对象,而是在数组手动赋值时进行加载初始化,这是因为我们new对象了