Java反射 —— 动态加载类

class.forName("类的全称");java

  • 不只表示了类的类类型,还表明了动态加载类。
  • 编译时刻加载类是静态加载类,运行时刻加载类是动态加载类。

编写一个Office.java以下:命令行

class Office {
	public static void main(String[] args) {
		if ("Word".equals(args[0])) {
			Word w = new Word();
			w.start();
		}
		if ("Excel".equals(args[0])) {
			Excel e = new Excel();
			e.start();
		}
	}
}

而后用命令行去编译该文件,会报错:code

由于Word类,Excel类都不存在。对象

如今把Word类补全,并编译经过:blog

class Word {
	public static void start() {
		System.out.println("word...start...");
	}
}

此时再去编译Office.java,就只会提示Excel类找不到:接口

经过new建立对象,是静态加载类,在编译时刻就要去加载全部可能使用到的类,无论某些类是否真的须要用到。io

如今咱们只想用Word,但程序一直在报错:Excel这个类找不到。实际应用当中,咱们但愿Word存在,Word就能用,当要使用Excel的时候,再提示咱们Excel找不到。这个程序就没办法作到,若是未来有许多功能,只要有一个功能有问题,其余全部功能就都没法使用,这就是编译时刻加载致使的。编译

 

咱们如今想要作到用哪一个类就加载哪一个类,不用就不加载。经过动态加载类就能够解决该问题。class

建立一个OfficeBetter.java,以下:程序

class OfficeBetter {
	public static void main(String[] args) {
		try {
			//动态加载类,在运行时刻加载
			Class c = Class.forName(args[0]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

此时编译该类不会报任何错。传入Word参数运行也不会报错:

只有当咱们传入不存在的类时,运行才会报错(但编译不会保存):

 

接下来,咱们能够经过类类型去建立对象,那么问题就来了:

class OfficeBetter {
	public static void main(String[] args) {
		try {
			//动态加载类,在运行时刻加载
			Class c = Class.forName(args[0]);
			//经过类类型,建立该类的对象
			//Word w = (Word) c.newInstance();
			//Excel e = (Excel) c.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

咱们这里是该建立Word对象呢,仍是该建立Excel对象呢,或者咱们传入的是其余对象又该怎么办呢?

若是咱们想适应以后传入的全部对象,咱们就须要提供一个统一的标准,建立接口类OfficeAble.java,以下:

interface OfficeAble {
	public void start();
}

而后让咱们的类遵循该标准:

class Word implements OfficeAble {
	public void start() {
		System.out.println("word...start...");
	}
}

这样咱们就能够经过这个标准,建立全部实现了该接口的对象:

class OfficeBetter {
	public static void main(String[] args) {
		try {
			//动态加载类,在运行时刻加载
			Class c = Class.forName(args[0]);

			//经过类类型,建立该类的对象
			//Word w = (Word) c.newInstance();
			//Excel e = (Excel) c.newInstance();

			//经过标准接口建立对象
			OfficeAble oa = (OfficeAble) c.newInstance();
			//调用对象方法
			oa.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

此时从新编译上面的文件,运行Word,就不会报错:

若是想让Excel也可使用,只需让其实现OfficeAble接口就能够(不须要从新编译OfficeBetter.java),一样的,未来添加了更多新的实现,都只要遵循该标准添加新的类,OfficeBetter这个类永远都不须要修改,这就是动态加载类。

通常来讲功能性的类,咱们都会使用动态加载类,而不使用静态加载类。

相关文章
相关标签/搜索