`
houjx
  • 浏览: 7791 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

探索Class的奥秘(二)——forName方法

阅读更多

Class类的forName方法是进行反射的核心,它让我们可以随意加载指定的类。Class分别提供了两个forName方法,一个是单参数的,我们只需要把一个表示类的名称的String传进去就可以获得这个类的类型(Class)对象,从而可以进一步进行实例化操作。而另一个三参数的forName方法则是本次的重点。

三个参数分别为String nameboolean initialize以及ClassLoader loader

 

 

String name参数指的是类的名称与单参数forName方法的参数是相同意义的。

 

ClassLoader loader参数指的是类的加载器,一般每个类都有指定的加载器,不可随便选择。

 

boolean initialize参数指的是在进行类加载时是否执行静态代码块。如果此参数为true时,当我们加载类就会执行静态代码块;如果此参数为false时,当我们加载类时则不会执行静态代码块。通过如下代码我们可以看到效果:

 

public class Test{
	static{
		System.out.println("要先生蛋");
	}
	
	Test(){
		System.out.println("破壳啦~");
	}
}

class Test2 {
	public static void main(String[] args) {
		Class<? extends Object> c = null;
		try {
			c = Class.forName("Test", true, Test.class.getClassLoader());
			//c = Class.forName("Test", false, Test.class.getClassLoader());
			System.out.println("****类别准备实体化");
			//Object o = c.newInstance();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

 通过实例我们可以发现的确是如此的。

 

 

另一方面从这个方法我们不难推测Java的对象实例化过程大致可以分为两步,一步是加载类,一步是生成实例化对象。

在我们执行反射时,首先使用forName方法进行类的加载,再调用newInstance方法进行对象实例化。这样有利于我们进行动态的设计。

而我们一般使用的new关键字,则在进行实例化时把加载与实例化两步顺序执行。

 

对于ClassLoader loader这个参数,在查询过源码之后发现,如果该参数为nullJava会判断本地系统是否有获取加载器的权限,之所以如果是由于RMI可以通过URL来实例化远程对象,为了系统的安全才做出这样的机制。

在源码中,loadernull时并没有自动生成一个加载器就进行底层调用了,因此猜测加载器将由底层来实现,所以loader就为null了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics