java反射笔记

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

1.Class.forNameClass.forName(xxx.xx.xx)返回的是一个类首先你要明白在java里面任何class都要装载在虚拟机上才能运行。这句话就是装载类用的(和new不一样,要分清楚)。至于什么时候用,你可以考虑一下这个问题,给你一个字符串变量,它代表一个类的包名和类名,你怎么实例化它?只有你提到的这个方法了,不过要再加一点。Aa=(A)Class.forName(pacage.A).newInstance();这和你Aa=newA();是一样的效果。关于补充的问题答案是肯定的,jvm会执行静态代码段,你要记住一个概念,静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了。而且以后不会再走这段静态代码了。Class.forName(xxx.xx.xx)返回的是一个类Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段动态加载和创建Class对象,比如想根据用户输入的字符串来创建对象Stringstr=用户输入的字符串Classt=Class.forName(str);t.newInstance();在初始化一个类,生成一个实例的时候,newInstance()方法和new关键字除了一个是方法,一个是关键字外,最主要有什么区别?它们的区别在于创建对象的方式不一样,前者是使用类加载机制,后者是创建一个新类。那么为什么会有两种创建对象方式?这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。Java中工厂模式经常使用newInstance()方法来创建对象,因此从为什么要使用工厂模式上可以找到具体答案。例如:classc=Class.forName(“Example”);factory=(ExampleInterface)c.newInstance();其中ExampleInterface是Example的接口,可以写成如下形式:StringclassName=Example;classc=Class.forName(className);factory=(ExampleInterface)c.newInstance();进一步可以写成如下形式:StringclassName=readfromXMlConfig;//从xml配置文件中获得字符串classc=Class.forName(className);factory=(ExampleInterface)c.newInstance();上面代码已经不存在Example的类名称,它的优点是,无论Example类怎么变化,上述代码不变,甚至可以更换Example的兄弟类Example2,Example3,Example4……,只要他们继承ExampleInterface就可以。从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。但是使用newInstance()方法的时候,就必须保证:1、这个类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载javaAPI的那个加载器。现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。最后用最简单的描述来区分new关键字和newInstance()方法的区别:newInstance:弱类型。低效率。只能调用无参构造。new:强类型。相对高效。能调用任何public构造。下面内容转自介绍的是forName()和ClassLoader的loadClass方法。现在终于知道了为什么forName()是会执行static语句,因为默认情况它总是初始化这个被装载的类。关于forName()方法这个方法总是返回要加载的类的Class类的实例1、forName(StringclassName)单参数时,initialize=truea.总是使用当前类装载器(也就是装载执行forName()请求的类的类装载器)b.总是初始化这个被装载的类(当然也包括:装载、连接、初始化)2、forName(StringclassName,booleaninitialize,ClassLoaderloader)a.loader指定装载参数类所用的类装载器,如果null则用bootstrp装载器。b.initialize=true时,肯定连接,而且初始化了;c.false时,绝对不会初始化,但是可能被连接了,但是这里有个例外,如果在调用这个forName()前,已经被初始化了,那么返回的类型也肯定是被初始化的(当然,这里也暗含着:被同一个loader所装载的,而且这个类被初始化了)关于用户自定义的类装载器的loadClass()方法1、loadClass(Stringname)单参数时,resolve=falsea.如果这个类已经被这个类装载器所装载,那么,返回这个已经被装载的类型的Class的实例,否则,就用这个自定义的类装载器来装载这个class,这时不知道是否被连接。绝对不会被初始化b.这时唯一可以保证的是,这个类被装载了。但是不知道这个类是不是被连接和初始化了2、loadClass(Stringname,booleanresolve)a.resolve=true时,则保证已经装载,而且已经连接了。resolve=falses时,则仅仅是去装载这个类,不关心是否连接了,所以此时可能被连接了,也可能没有被连接2.java的getClass()函数Java反射学习所谓反射,可以理解为在运行时期获取对象类型信息的操作。传统的编程方法要求程序员在编译阶段决定使用的类型,但是在反射的帮助下,编程人员可以动态获取这些信息,从而编写更加具有可移植性的代码。严格地说,反射并非编程语言的特性,因为在任何一种语言都可以实现反射机制,但是如果编程语言本身支持反射,那么反射的实现就会方便很多。2.1获得类型类我们知道在Java中一切都是对象,我们一般所使用的对象都直接或间接继承自Object类。Object类中包含一个方法名叫getClass,利用这个方法就可以获得一个实例的类型类。类型类指的是代表一个类型的类,因为一切皆是对象,类型也不例外,在Java使用类型类来表示一个类型。所有的类型类都是Class类的实例。例如,有如下一段代码:Aa=newA();if(a.getClass()==A.class)System.out.println(equal);elseSystem.out.println(unequal);结果就是打印出“equal”。可以看到,对象a是A的一个实例,A某一个类,在if语句中使用a.getClass()返回的结果正是A的类型类,在Java中表示一个特定类型的类型类可以用“类型.class”的方式获得,因为a.getClass()获得是A的类型类,也就是A.class,因此上面的代码执行的结果就是打印出“equal”。特别注意的是,类型类是一一对应的,父类的类型类和子类的类型类是不同的,因此,假设A是B的子类,那么如下的代码将得到“unequal”的输出:Aa=newA();if(a.getClass()==B.class)System.out.println(equal);elseSystem.out.println(unequal);因此,如果你知道一个实例,那么你可以通过实例的“getClass()”方法获得该对象的类型类,如果你知道一个类型,那么你可以使用“.class”的方法获得该类型的类型类。2.2获得类型的信息在获得类型类之后,你就可以调用其中的一些方法获得类型的信息了,主要的方法有:getName():String:获得该类型的全称名称。getSuperClass():Class:获得该类型的直接父类,如果该类型没有直接父类,那么返回null。getInterfaces():Class[]:获得该类型实现的所有接口。isArray():boolean:判断该类型是否是数组。isEnum():boolean:判断该类型是否是枚举类型。isInterface():boolean:判断该类型是否是接口。isPrimitive():boolean:判断该类型是否是基本类型,即是否是int,boolean,double等等。isAssignableFrom(Classcls):boolean:判断这个类型是否是类型cls的父(祖先)类或父(祖先)接口。getComponentType():Class:如果该类型是一个数组,那么返回该数组的组件类型。此外还可以进行类型转换这类的操作,主要方法有:asSubclass(Classclazz):Class:将这个类型3.深入探讨Java类加载器简介:类加载器(classloader)是Java™中的一个很重要的概念。类加载器负责加载Java类的字节代码到Java虚拟机中。本文首先详细介绍了Java类加载器的基本概念,包括代理模式、加载类的具体过程和线程上下文类加载器等,接着介绍如何开发自己的类加载器,最后介绍了类加载器在Web容器和OSGi™中的应用。类加载器是Java语言的一个创新,也是Java语言流行的重要原因之一。它使得Java类可以被动态加载到Java虚拟机中并执行。类加载器从JDK1.0就出现了,最初是为了满足JavaApplet的需要而开发出来的。JavaApplet需要从远程下载Java类文件到浏览器中并执行。现在类加载器在Web容器和OSGi中得到了广泛的使用。一般来说,Java应用的开发人员不需要直接同类加载器进行交互。Java虚拟机默认的行为就已经足够满足大多数情况的需求了。不过如果遇到了需要与类加载器进行交互的情况,而对类加载器的机制又不是很了解的话,就很容易花大量的时间去调试ClassNotFoundException和NoClassDefFoundError等异常。本文将详细介绍Java的类加载器,帮助读者深刻理解Java语言中的这个重要概念。下面首先介绍一些相关的基本概念。3.1类加载器基本概念顾名思义,类加载器(classloader)用来加载Java类到Java虚拟机中。一般来说,Java虚拟机使用Java类的方式如下:Java源程序(.java文件)在经过Java编译器编译之后就被转换成Java字节代码(.class文件)。类加载器负责读取Java字节代码,并转换成java.lang.Class类的一个实例。每个这样的实例用来表示一个Java类。通过此实例的newInstance()方法就可以创建出该类的一个对象。实际的情况可能更加复杂,比如Java字节代码可能是通过工具动态生成的,也可能是通过网络下载的。基本上所有的类加载器都是java.lang.ClassLoader类的一个实例。下面详细介绍这个Java类。java.lang.ClassLoader类介绍java.lang.ClassLoader类的基本职责就是根据一个指定的类的名称,找到或者生成其对应的字节代码,然后从这些字节代码中定义出一个Java类,即java.lang.Class类的一个实例。除此之外,ClassLoader还负责加载Java应用所需的资源,如图像文件和配置文件等。不过本文只讨论其加载类的功能。为了完成加载类的这个职责,ClassLoader提供了一系列的方法,比较重要的方法如表1所示。关于这些方法的细节会在下面进行介绍。表1.ClassLoader中与加载类相关的方法方法说明getParent()返回该类加载器的父类加载器。loadCla

1 / 14
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功