`
tj2008wangqing
  • 浏览: 14577 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java 中反射 代理

阅读更多


Java反射学习

    所谓反射,可以理解为在运行时期获取对象类型信息的操作。传统的编程方法要求程序员在编译阶段决定使用的类型,但是在反射的帮助下,编程人员可以动态获取这些信息,从而编写更加具有可移植性的代码。严格地说,反射并非编程语言的特性,因为在任何一种语言都可以实现反射机制,但是如果编程语言本身支持反射,那么反射的实现就会方便很多。

1,获得类型类

    我们知道在Java中一切都是对象,我们一般所使用的对象都直接或间接继承自Object类。Object类中包含一个方法名叫getClass,利用这个方法就可以获得一个实例的类型类。类型类指的是代表一个类型的类,因为一切皆是对象,类型也不例外,在Java使用类型类来表示一个类型。所有的类型类都是Class类的实例。例如,有如下一段代码:

A a = new A();

if(a.getClass()==A.class)

System.out.println("equal");

else System.out.println("unequal");

结果就是打印出 “equal”。

    可以看到,对象a是A的一个实例,A某一个类,在if语句中使用a.getClass()返回的结果正是A的类型类,在Java中表示一个特定类型的类型类可以用“类型.class”的方式获得,因为a.getClass()获得是A的类型类,也就是A.class,因此上面的代码执行的结果就是打印出 “equal”。特别注意的是,类型类是一一对应的,父类的类型类和子类的类型类是不同的,因此,假设A是B的子类,那么如下的代码将得到 “unequal”的输出:

A a = new A();

if(a.getClass()==B.class)

System.out.println("equal");

else System.out.println("unequal");

因此,如果你知道一个实例,那么你可以通过实例的“getClass()”方法获得该对象的类型类,如果你知道一个类型,那么你可以使用“.class”的方法获得该类型的类型类。

2,获得类型的信息

在获得类型类之后,你就可以调用其中的一些方法获得类型的信息了,主要的方法有:

getName():String:获得该类型的全称名称。

getSuperClass():Class:获得该类型的直接父类,如果该类型没有直接父类,那么返回null。

getInterfaces():Class[]:获得该类型实现的所有接口。

isArray():boolean:判断该类型是否是数组。

isEnum():boolean:判断该类型是否是枚举类型。

isInterface():boolean:判断该类型是否是接口。

isPrimitive():boolean:判断该类型是否是基本类型,即是否是int,boolean,double等等。

isAssignableFrom(Class cls):boolean:判断这个类型是否是类型cls的父(祖先)类或父(祖先)接口。

getComponentType():Class:如果该类型是一个数组,那么返回该数组的组件类型。

此外还可以进行类型转换这类的操作,主要方法有:

asSubclass(Class clazz):Class:将这个类型

类型类提前的请他方法 见api

3 实例化一个类
         public class Test {
/**
* java类加载器在装载类的时候是需要加载的,只有当一个类要使用的时候,类加载器才
* 加载这个类并实例化。下面以例子为例,说明类加载的过程
* @author guoqing.wang@renren-inc.com
* @version createDate 2012-11-8 下午12:31:02
* @param args
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//A a=new A();
//a.print();
//B b=new B();
//b.print();
//new A();
//以下是两种实现类实例话,
//Class<?> aClass=Class.forName("com.classLoader.A");//单独加载,并没有实例化,只执行静态块,且只执行一次。
/*Class<?> alaze=Class.forName("com.classLoader.A", false, A.class.getClassLoader());//这种加载方式,是不初始化静态模块的
alaze.newInstance();*///实例化时初始化静态模块和构造函数
//A a = (A) Class.forName("com.classLoader.A").newInstance();//实例化时才执行构造函数。
//aClass.newInstance();//实例化时才执行构造函数。
//new A();

//A.class.newInstance();

A.class.getClassLoader().loadClass("com.classLoader.A").newInstance();




}

}
当classloader有类需要载入时,先让其parent搜寻路径帮忙载入,如果parent找不到,再由自己搜寻路径进行载入。ClassLoader在运行期会以父/子的层次结构存在,每个ClassLoader实例都有其父ClassLoader的引用,而父ClassLoader并没有持有子ClassLoader的引用,从而形成一条单向链,当一个类装载请求被提交到某个ClassLoader时,默认的类装载过程如下:
�检查这个类有没有被装载过,如果已经装载过,则直接返回
�调用父ClassLoader去装载类,如果装载成功则返回
�调用自身的装载类方法,如果装载成功则返回
�上述所有步骤都没有成功装载到类,抛出ClassNotFoundException每一层次的ClassLoader都重复上述动作。
简单说,当Classloader链上的某一Classloader收到类装载请求时,会按顺序向上询问其所有父节点,直至最顶端(BootstrapClassLoader),任何一个节点成功受理了此请求,则返回,如果所有父节点都不能受理,这时候才由被请求的Classloader自身来装载这个类,如果仍然不能装载,则抛出异常
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics