




免费预览已结束,剩余11页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java反射机制一、 Java反射机制1、什么是java语言的反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。2、Java反射机制主要提供了以下功能:l 在运行时判断任意一个对象所属的类l 在运行时构造任意一个类的对象l 在运行时判断任意一个类所具有的成员变量和方法l 在运行时调用任意一个对象的方法l 生成动态代理3、Java反射的用途Java 语言的反射机制提供了一种非常通用的动态连接程序组件的方法。它允许你的程序创建和维护任何类的对象(服从安全限制),而不需要提前对目标类进行硬编码。这些特征使得反射在创建与对象一同工作的类库中的通用方法方面非常有用。例如,反射经常被用于那些数据库,XML,Eclipse或者其它的外部的框架中,如Struts,Spring,Hibernate。二、类加载机制与ClassLoader1、什么是类加载器 Classloader与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头CodeSegment(代码段)运行,负责加载Java class的这部分就叫做Class Loader。因此Classloader也叫做类加载器。2、Java类加载机制l 类加载是动态执行的,也就是说当我们用到的时候才会去加载,如果不用的话,就不会去加载我们的类。l 类加载有两种方式:第一种就是new一个对象的时候,另一种就是当一个类的静态代码被调用的时候l 静态初始化语句块在加载时只执行一次,而初始化语句块在每次new出新的对象是都会执行,等同于构造方法中的语句。l java-verbose:class可以观察类的具体加载过程以下代码可以说明类加载过程:package com.puckasoft.reflect;public class TestClassLoader public static void main(String args) new A();System.out.println(after load A);new B();new C();new C();new D();new D();class A class B class C static System.out.println(invoke C static block);class D System.out.println(invoke D init block);运行结果:Opened E:ProgramMyEclipse 6.0jrelibrt.jarOpened E:ProgramMyEclipse 6.0jrelibjsse.jarOpened E:ProgramMyEclipse 6.0jrelibjce.jarOpened E:ProgramMyEclipse 6.0jrelibcharsets.jar. . .Loaded java.lang.Object from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.io.Serializable from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.Comparable from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.CharSequence from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.String from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.reflect.GenericDeclaration from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.reflect.Type from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.reflect.AnnotatedElement from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.Class from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.Cloneable from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.ClassLoader from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.System from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.Throwable from E:ProgramMyEclipse Loaded com.puckasoft.reflect.TestClassLoader from file:/E:/MyCode/Teaching/Reflect/WebRoot/WEB-INF/classes/Loaded com.puckasoft.reflect.A from file:/E:/MyCode/Teaching/Reflect/WebRoot/WEB-INF/classes/after load ALoaded com.puckasoft.reflect.B from file:/E:/MyCode/Teaching/Reflect/WebRoot/WEB-INF/classes/Loaded com.puckasoft.reflect.C from file:/E:/MyCode/Teaching/Reflect/WebRoot/WEB-INF/classes/invoke C static blockLoaded com.puckasoft.reflect.D from file:/E:/MyCode/Teaching/Reflect/WebRoot/WEB-INF/classes/invoke D init blockinvoke D init blockLoaded java.lang.Shutdown from E:ProgramMyEclipse 6.0jrelibrt.jarLoaded java.lang.Shutdown$Lock from E:ProgramMyEclipse 6.0jrelibrt.jar从运行结果可以看出来,JVM首先Load进来的是Object类,然后load一些核心类或接口。比如System类,String类,Serializable接口等,接着开始load我们自定的TestClassLoader类,进入main方法后,JVM依次load了A、B、C、D类。加载完A后,打印“after load A”再加载B,说明类是动态加载,需要时才加载。“invoke C static block”打印一次,说明静态初始化语句块只在类加载后才调用,且只调用一次。“invoke D init block”打印两次,说明初始化语句块在每次实例化对象时就会被调用。3、JDK 内置 ClassLoaderJVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,Bootstrap ClassLoader是用本地代码实现的,它负责加载核心Java Class(即所有java.*开头的类)。另外JVM还会提供两个ClassLoader,它们都是用Java语言编写的,由Bootstrap ClassLoader加载;其中Extension ClassLoader负责加载扩展的Java class(例如所有javax.*开头的类和存放在JRE的ext目录下的类),Application ClassLoader负责加载应用程序自身的类。如下表:Class loader 类型用途bootstrap class loader用本地语言实现如:汇编,C或C+用于加载jdk的核心类extesion class loader加载jre/lib/ext中的类application class loader加载自定义类ClassLoader.getSystemClassLoader()other class loaderSecureClassLoaderURLClassLoader以下代码显示了不同类的是类加载器package com.puckasoft.reflect;public class TestJDKClassLoader public static void main(String args) System.out.println(String的类加载器是: + String.class.getClassLoader(); System.out.println(JDK_HOMEjrelibextsunjco_provider.jar中的AESCipher的类加载器:+vider .AESCipher.class.getClassLoader().getClass().getName();System.out.println(自定义类TestJDKClassLoader的类加载器是:+ TestJDKClassLoader.class.getClassLoader().getClass().getName();运行结果:String的类加载器是:nullJDK_HOMEjrelibextsunjco_provider.jar中的AESCipher的类加载器:sun.misc.Launcher$ExtClassLoader自定义类TestJDKClassLoader的类加载器是:sun.misc.Launcher$AppClassLoaderString的类加载器是bootstrap class loader,由于bootstrap class loader不是用java实现的,所以显示为null4、JDK Class Loader的层次关系Bootstrap class loaderExtension class loaloaderapplication class loader. . . . .classloader在load class的时候首先找上一层loader是不是load过了,如果已经load了,就不能再次load每个ClassLoader加载Class的过程是: 1.检测此Class是否载入过(即在cache中是否有此Class),如果有到8,如果没有到2 2.如果parent classloader不存在(没有parent,那parent一定是bootstrap classloader了),到4 3.请求parent classloader载入,如果成功到8,不成功到5 4.请求jvm从bootstrap classloader中载入,如果成功到8 5.寻找Class文件(从与此classloader相关的类路径中寻找)。如果找不到则到7. 6.从文件中载入Class,到8. 7.抛出ClassNotFoundException. 8.返回Class. 三、Java Reflect APIJava的反射机制的实现要借助于4个类:Class,Constructor,Field,Method;其中class代表的是类对象,Constructor类的构造器对象,Field类的属性对象,Method类的方法对象。通过这四个对象我们可以粗略的看到一个类的各个组成部分。1、java.lang.ClassClass,反射的核心类,所有的操作都是围绕该类来生成的,Class类十分的特殊,和其他的类一样继承与Object类,其实例用来表达java在运行时的classes和interface ,也用来表达enum、array、primitive java types(boolean, byte, char, short, int, long, float, double)以及关键字void。当一個class被加载,或当类加载器(class loader)的defineClass()被JVM 调用,JVM 便自动的产生一個Class object实例。Class 类用以表达Java程序运行时的classes和interfaces,也用来表达enum、array、primitive Java types(boolean, byte, char, short, int, long, float, double)以及关键词void。Class对象的取得途径如下:获得Class对象的方法示例运用getClass()注:每个class 都有此函数String str = abc;Class c1 = str.getClass();运用Class.getSuperclass()Button b = new Button();Class c1 = b.getClass();Class c2 = c1.getSuperclass();运用static methodClass.forName()(最常被使用)Class c1 = Class.forName (java.lang.String);Class c2 = Class.forName (java.awt.Button);Class c3 = Class.forName (java.util.LinkedList$Entry);Class c4 = Class.forName (I);Class c5 = Class.forName (I);运用.class 语法Class c1 = String.class;Class c2 = java.awt.Button.class;Class c3 = Main.InnerClass.class;Class c4 = int.class;Class c5 = int.class;运用primitive wrapper classes的TYPE 语法Class c1 = Boolean.TYPE;Class c2 = Byte.TYPE;Class c3 = Character.TYPE;Class c4 = Short.TYPE;Class c5 = Integer.TYPE;Class c6 = Long.TYPE;Class c7 = Float.TYPE;Class c8 = Double.TYPE;Class c9 = Void.TYPE;实例代码片段public static Class getClass() throws ClassNotFoundException Class clazz = null;/ 对象的getClass()clazz = new Date().getClass();/ 通过类名加载clazz = Class.forName(java.util.Date);/ 类型.classclazz = Date.class;/ 类 类型clazz = Serializable.class;/ 接口 类型clazz = int.class;/ 基本数据 类型clazz = int.class;/ 基本数据数组 类型clazz = String.class;/ 类数组 类型/ 运行包装类的.TYPEclazz = Boolean.TYPE;clazz = Void.TYPE;return clazz;2、Java classes 组成分析:Method,Constructor,Field我们用java.util.HashMap为例,观察java class的组成。package java.util; /1import java.io.*;. /2public /3class HashMap /4 /5extends AbstractMap /6implements Map, Cloneable, Serializable /7static class Entry implements Map.Entry . /8 public HashMap(). /9 public V put(K key, V value). /10transient int size; /11下表为java class 内部结构及对应的api方法Java class 内部模块Java class 内部模块说明相应之Reflection API,多半为Class methods。返回值类型(return type)(1) packageclass隶属哪packagegetPackage()Package(2) importclass导入哪classes无直接对应之API。(3) modifierclass(或methods, fields)的属性int getModifiers()Modifier.toString(int)Modifier.isInterface(int)intStringbool(4) class name or interface nameclass/interface名称getName()String(5) type parameters参数化类型的名称getTypeParameters() TypeVariable (6) base classbase class(只可能一个)getSuperClass()Class(7)implemented interfaces实现有哪interfacesgetInterfaces()Class(8) inner classes内部classesgetDeclaredClasses()Class(8) outer class如果我们观察的class 本身是inner classes,那么相对它就会有个outer class。getDeclaringClass()Class(9) constructors构造函数getDeclaredConstructors()不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。Constructor(10) methods操作函数getDeclaredMethods()不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。Method(11) fields字段(成员变量)getDeclaredFields()不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。Field以下是一个实例用于打印String的内部结构,包括String的类定义,成员变量定义,构造方法定义和方法定义。它的功能类似与Eclipse中的OutLine面板显示的信息。package com.puckasoft.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;public class TestClass public static void main(String args) Class clazz = String.class;StringBuffer stringBuffer = new StringBuffer();/ 包 - PackagePackage _package = clazz.getPackage();if (_package != null) stringBuffer.append(package + _package.getName() + n);/ 类修饰符 - Modifier/ clazz.getModifiers()返回一个数字-2进制数对应下表能推算出修饰符的组合/ 1 1 1 1 1/ final static protected private public/ 关键词 interface 已含于modifierint i = clazz.getModifiers();if (i != 0) stringBuffer.append(Modifier.toString(i) + );if (!Modifier.isInterface(i) stringBuffer.append(class );/ 类、接口名stringBuffer.append(clazz.getSimpleName() + );/ 类直接父类Class _super = clazz.getSuperclass();if (_super != null & _super != Object.class) stringBuffer.append(extends + _super.getSimpleName() + );/ 类直接实现接口Class _interfaces = clazz.getInterfaces();if (_interfaces != null & _interfaces.length 0) stringBuffer.append(implements );for (Class _interface : _interfaces) stringBuffer.append(_interface.getSimpleName() + ,);stringBuffer.deleteCharAt(stringBuffer.length() - 1);stringBuffer.append(n);/ 类的属性(修饰符+属性类型+属性名) - FieldField fields = clazz.getDeclaredFields();if (fields != null & fields.length 0) for (Field field : fields) / 属性修饰符/ displayModifiers(field, stringBuffer);int i1 = field.getModifiers();if (i1 != 0) stringBuffer.append(Modifier.toString(i1) + );/ 属性类型stringBuffer.append(field.getType().getSimpleName() + );/ 属性的名称stringBuffer.append(field.getName() + n);/ 类的构造方法(修饰符+类名+参数列表) -ConstructorConstructor constructors = clazz.getDeclaredConstructors();if (constructors != null & constructors.length 0) for (Constructor constructor : constructors) / 构造方法修饰符int i1 = constructor.getModifiers();if (i1 != 0) stringBuffer.append(Modifier.toString(i1) + );/ 构造方法名stringBuffer.append(clazz.getSimpleName() + );/ 参数列表Class paramTypes = constructor.getParameterTypes();stringBuffer.append();if (paramTypes != null & paramTypes.length 0) for (Class paramType : paramTypes) stringBuffer.append(paramType.getSimpleName() + ,);stringBuffer.deleteCharAt(stringBuffer.length() - 1);stringBuffer.append()n);/ 类的方法(修饰符+返回值类型+方法名+参数列表)-MethodMethod methods = clazz.getDeclaredMethods();if (methods != null & methods.length 0) for (Method method : methods) / 方法修饰符int i1 = method.getModifiers();if (i1 != 0) stringBuffer.append(Modifier.toString(i1) + );/ 方法返回值stringBuffer.append(method.getReturnType().getSimpleName()+ );/ 方法名stringBuffer.append(method.getName();/ 参数列表Class paramTypes = method.getParameterTypes();stringBuffer.append();if (paramTypes != null & paramTypes.length 0) for (Class paramType : paramTypes) stringBuffer.append(paramType.getSimpleName() + ,);stringBuffer.deleteCharAt(stringBuffer.length() - 1);stringBuffer.append()n);System.out.println(stringBuffer.toString();运行结果:package java.langpublic final class String implements Serializable,Comparable,CharSequenceprivate final char valueprivate final int offsetprivate final int countprivate int hashprivate static final long serialVersionUIDprivate static final ObjectStreamField serialPersistentFieldspublic static final Comparator CASE_INSENSITIVE_ORDERpublic String (char,int,int)public String (int,int,int)public String (byte,int,int,int)public String (byte,int)public String (char)public String (String)public String (byte,String)public String (byte,int,int)public String (byte)public String (StringBuffer)public String (StringBuilder)String (int,int,char)public String (byte,int,int,String)public String ()public int hashCode()public int compareTo(String)public volatile int compareTo(Object)public int indexOf(int,int)public int indexOf(int)public int indexOf(String)public int indexOf(String,int)static int indexOf(char,int,int,char,int,int,int)public boolean equals(Object)public String toString()public char charAt(int)private static void checkBounds(byte,int,int)public int codePointAt(int)public int codePointBefore(int)public int codePointCount(int,int)public int compareToIgnoreCase(String)public String concat(String)public boolean contains(CharSequence)public boolean contentEquals(StringBuffer)public boolean contentEquals(CharSequence)public static String copyValueOf(char,int,int)public static String copyValueOf(char)public boolean endsWith(String)public boolean equalsIgnoreCase(String)public static transient String format(Locale,String,Object)public static transient String format(String,Object)public byte getBytes()public byte getBytes(String)public void getBytes(int,int,byte,int)void getChars(char,int)public void getChars(int,int,char,int)public native String intern()static int lastIndexOf(char,int,int,char,int,int,int)public int lastIndexOf(int)public int lastIndexOf(int,int)public int lastIndexOf(String,int)public int lastIndexOf(String)public int length()public boolean matches(String)public int offsetByCodePoints(int,int)public boolean regionMatches(boolean,int,String,int,int)public boolean regionMatches(int,String,int,int)public String replace(CharSequence,CharSequence)public String replace(char,char)public String replaceAll(String,String)public String replaceFirst(String,String)public String split(String,int)public String split(String)public boolean startsWith(String)public boolean startsWith(String,int)public CharSequence subSequence(int,int)public String substring(int)public String substring(int,int)public char toCharArray()public String toLowerCase()public String toLowerCase(Locale)public String toUpperCase(Locale)public String toUpperCase()public String trim()public static String valueOf(char)public static String valueOf(char)public static String valueOf(int)public static String valueOf(long)public static String valueOf(float)public static String valueOf(double)public static String valueOf(Object)public static String valueOf(boolean)public static String valueOf(char,int,int)四、 Reflection 的三个动态性质1、运行时生成实例在java机制中有两种方式可以动态实例化一个对象,l 其一调用无参的构造方法public T newInstance() -java.lang.Classl 其二调用带参数的构造方法public T newInstance(Object.initargs)-java.lang.reflect. Constructorinitargs - 将作为变量传递给构造方法调用的对象数组;基本类型的值被包装在适当类型的包装器对象(如 Float 中的 float)中。 package com.puckasoft.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class TestConstructor public static void main(String args) throws InstantiationException,IllegalAccessException, SecurityException, NoSuchMethodException,IllegalArgumentException, InvocationTargetException /调用String空参构造方法创建String对象String string = String.class.newInstance();/得到String(char,int,int)这个构造方法Constructor constructor = String.class.getConstructor(new Class char.class, int.class, int.class );char chars = a, b, c ;/调用String(char,int,int)构造方法生成String对象的实例string = (String) constructor.newInstance(chars, 0, 2);System.out.println(string);2、运行时调用方法l 根据方法名称和参数类型得到Method对象public Method getDeclaredMethod(Stringname,.parameterTypes)java.lang.Classname - 方法名 parameterTypes - 参数数组 l 调用方法public Object invoke(Objectobj, Object.args)java.lang.reflect.Methodobj :从中调用底层方法的对 a
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025供应商合作合同范本
- 北师大版初中英语九年级上册 Unit 5 阅读理解(科普类)试卷及答案
- 混合式学习模式2025年在线教育学员学习动机分析与课程改进方案
- 雨水工程成品保护方案(3篇)
- 吊顶工程维修施工方案(3篇)
- 东莞管道工程方案(3篇)
- 工程项目清欠计划方案(3篇)
- 公路工程主动防护方案(3篇)
- 锅炉基础知识培训书籍课件
- 水塘改造工程方案设计(3篇)
- 解读《义务教育体育与健康课程标准(2022年版)》2022年体育与健康新课标专题PPT
- 2019版外研社高中英语必修三单词默写表
- 食堂合作协议范本食堂档口合作协议.doc
- 直接还原铁生产工艺
- 建筑识图题库及答案
- 《幂的运算》习题精选及答案
- 异质结TCO设备:RPD与PVD比较分析(2021年).doc
- PPT汇报评分表(共1页)
- ESD防静电培训教材.ppt
- 《春》复习课件
- 《口袋妖怪漆黑的魅影5.0》图文攻略(全周目)
评论
0/150
提交评论