首页 > 代码库 > 编程基础知识——java类加载

编程基础知识——java类加载

java类加载


先来看一段小程序:

package com;

public class Main1 {

	static {
		System.out.println("1111") ;
	}
	
	
	public static void main(String[] args) {
		System.out.println("2222") ;
	}

}

输出结果为:

1111
2222

其中static的执行时机就是class被 classloader加载的时候执行。

这有什么用?看下面代码

package com;

import java.util.ArrayList;
import java.util.List;

public class Main1 {

	public static List<String> keyNames = new ArrayList<String>();
	
	static {
		keyNames.add("语文");
		keyNames.add("数学");
		keyNames.add("英语");
		keyNames.add("物理");
		keyNames.add("化学");
		keyNames.add("历史");
		keyNames.add("政治");
	}
	
	
	public static void main(String[] args) {
		
		for(String key : keyNames)
			System.out.printf("key = %s\n", key);
		
	}
}

程序输出结果:

key = 语文
key = 数学
key = 英语
key = 物理
key = 化学
key = 历史
key = 政治

讨论:

任何语言任何平台开发的时候我们都需要有静态的全局资源,有些是单独的字段,比如应用系统名称,版本,服务器下载地址等等。这些静态资源可以直接赋值加载。但是不是所有资源都能够赋值初始化,比如某些静态资源是集合类型的,比如一个城市下面有多少个行政区,一个学校有多少个教室,比如上面例子程序中有多少个学科。这些数据最后可能会影响显示多少个page,会将应用程序分成多个tab。

一般的方法是singleton(单例模式),在初始化的时候赋值添加这些集合成员。

但是使用java这个static 代码区特性,可以定义一段代码,在.class文件被加载到虚拟机的过程中自动执行这段代码初始化,它甚至比main函数还要先执行。

static块代码,可以有多个,比如下面代码:

package com;

import java.util.ArrayList;
import java.util.List;

public class Main1 {

	public static List<String> keyNames = new ArrayList<String>();
	
	static {
		keyNames.add("语文");
		keyNames.add("数学");
		keyNames.add("英语");
		keyNames.add("物理");
		keyNames.add("化学");
		keyNames.add("历史");
		keyNames.add("政治");
	}
	
	static {
		keyNames.add("1");
		keyNames.add("2");
		keyNames.add("3");
		keyNames.add("4");
		keyNames.add("5");
		keyNames.add("6");
		keyNames.add("7");
	}
	
	public static void main(String[] args) {
		
		for(String key : keyNames)
			System.out.printf("key = %s\n", key);
		
	}
}

也就是可以分模块加载不同业务模块的静态数据。


static 模块的代码,只有在这个class被使用的时候加载,看下面例子代码:

package com;


class Test {
	static {
		System.out.println("Test.class 被加载到虚拟机。");
	}
	
	public static void test(){}
}

public class Main1 {

	static {
		System.out.println("Main1.class 被加载到虚拟机。");
	}
	
	public static void main(String[] args) {
		
		System.out.println("Test.test() 方法被执行之前。");
		
		Test.test();
		
		System.out.println("Main1.main 方法被执行之后。");
		
	}
}

上面代码输出内容为:

Main1.class 被加载到虚拟机。
Test.test() 方法被执行之前。
Test.class 被加载到虚拟机。
Main1.main 方法被执行之后。

可以看到,Test的static代码块,并不是程序一开始执行就执行了,而是要等待Test类被使用的时候,才会被执行。

这样也不用担心程序一开始加载资源过多什么的。


多掌握这些技巧,可以在特定的需求下,不用写一些别扭的代码,任何需求都可以实现,但是要找到最合适的方式实现,就需要多积累一些技巧。