JAVA中的反射机制(内含大量实例)及循环删除文件夹
- 格式:doc
- 大小:75.00 KB
- 文档页数:20
Java中的反射机制详解Java作为一种编程语言,具有许多强大的特性和功能。
其中,反射机制是其中的重要部分之一。
通过反射机制,Java程序可以在运行时动态地获取类的信息、构造对象、调用方法和访问属性等。
本文将详细介绍Java中的反射机制。
一、什么是反射机制?Java中的反射机制指的是在程序运行时动态获取类的信息并对其进行操作的能力。
通过反射机制,Java程序可以在运行时获取类的属性、方法和构造器等信息,并对其进行操作。
利用反射机制可以实现动态代理、框架开发、自动化测试等功能。
二、反射机制的基本原理Java程序在编译时会将类的信息编译成.class文件。
在程序运行时,JVM会将.class文件加载到内存中,并生成一个Class对象,该对象包含了类的所有信息。
通过Class对象,Java程序可以获取类的构造器、方法、属性等信息,并对它们进行操作。
三、反射机制的使用Java中的反射机制主要通过ng.reflect包中的类和接口实现。
在这个包中,最常用的类包括Class、Constructor、Method和Field等。
下面我们将分别介绍这些类的用法。
1、Class类Class类是Java中用来表示类的类。
在Java程序中,每个类都有一个对应的Class对象,可以使用该对象获取类的信息。
获取Class对象有以下三种方式:(1)使用类的.class属性获取:Class clazz = MyClass.class;(2)使用Class的forName()方法获取:Class clazz = Class.forName("com.example.MyClass");(3)使用对象的getClass()方法获取:MyClass obj = new MyClass();Class clazz = obj.getClass();通过Class对象可以获取类的信息,如:(1)类的名称:String name = clazz.getName(); // com.example.MyClass(2)类的简单名称:String simpleName = clazz.getSimpleName(); // MyClass(3)类的包路径:Package pkg = clazz.getPackage(); // com.example(4)类的修饰符:int modifiers = clazz.getModifiers(); // 返回访问修饰符列表(5)类的父类:Class superClass = clazz.getSuperclass(); // 返回父类的Class对象2、Constructor类Constructor类用于描述类的构造器。
Java 反射一、Java 语言的反射机制在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答案是肯定的。
这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。
Java 反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类。
在运行时构造任意一个类的对象。
在运行时判断任意一个类所具有的成员变量和方法。
在运行时调用任意一个对象的方法Reflection 允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces (例如Serializable),也包括fields和methods的所有信息,并可于运行时改变fields内容或调用methods。
那么反射这么厉害,java是不是动态语言呢?来看一下动态语言百科上的定义:动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化。
从这个角度看很明显,发现java不是动态语言尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。
这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。
换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或调用其methods。
二、Java Reflection API 简介在JDK中,主要由以下类来实现Java反射机制,这些类都位于ng.reflect包中Class类:代表一个类。
反射概述1反射的概述1.1什么是反射每个.class文件被加载到内存后都是一个Class类的对象!例如Demo.class加载到内存后它是Class<Demo>类型的一个对象。
反射就是通过Class对象获取类型相关的信息。
一个Class对象就表示一个.class文件,可以通过Class对象获取这个类的构造器、方法,以及成员变量等。
反射是Java的高级特性,在框架中大量被使用!我们必须要了解反射,不然无法学好JavaWeb 相关的知识!1.2反射相关类与反射相关的类:●Class:表示类;●Field:表示成员变量;●Method:表示方法;●Constructor:表示构造器。
2Class类2.1获取Class类获取Class类的三种基本方式:●通过类名称.class,对基本类型也支持;Class c = int.class;Class c = int[].class;Class c = String.class●通过对象.getClass()方法Class c = obj.getClass();●Class.forName()通过类名称加载类,这种方法只要有类名称就可以得到Class;Class c = Class.forName(“cn.itcast.Demo”);2.2Class类的常用方法●String getName():获取类名称,包含包名;●String getSimpleName():获取类名称,不包含包名;●Class getSupperClass():获取父类的Class,例如:new Integer(100).getClass().getSupperClass()返回的是Class<Number>!但new Object().getSupperClass()返回的是null,因为Object没有父类;●T newInstance():使用本类无参构造器来创建本类对象;●boolean isArray():是否为数组类型;●boolean isAnnotation():是否为注解类型;●boolean isAnnotationPresent(Class annotationClass):当前类是否被annotationClass注解了;●boolean isEnum():是否为枚举类型;●boolean isInterface():是否为接口类型;●boolean isPrimitive():是否为基本类型;●boolean isSynthetic():是否为引用类型;2.3通过反射创建对象3ConstructorConstructor表示一个类的构造器。
首页资讯精华论坛问答博客专栏群组更多 ▼您还未登录 !登录注册jczghost博客微博相册收藏留言关于我java反射机制总结博客分类:java-高级JavaStrutsBean框架Mobile经过多方面的资料搜集整理,写下了这篇文章,本文主要讲解java的反射和内省机制,希望对大家有点帮助,也希望大家提出不同的看法!1).反射是java的基础技术,在我们用到的框架如:struts,spring,hibernate,junit等都用到了反射技术,所以了解反射对我们来说也很重要。
要了解反射技术,必须要了解一个类Class类。
2).平时我们定义class的时候都是小写,这里讲的Class是大写,此时它代表一类事物,java类用于描述一类事物的共性,如该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则是由这个类的实例对象来确定,不同的事物对象有不同的属性值。
java程序中的java类,属于同一类事物,描述这类事物的Java类名就是Class.,就比如众多的人可以用一个Person类表示一样,众多的java类用Class来表示。
3).Class类代表Java类,它(Class类)的各个实例对象分别对应各个类在内存中的字节码,那么什么叫字节码呢? java源程序被编译成一堆二进制的class代码,当我们需要用到某个类时,首先把类的字节码加载到内存中来,然后再用该字节码去复制一个个的实例对象来,每份字节码都是Class类的实例对象,即Class类的实例对象就代表内存中字节码。
如:public static void main(String[] args) throws Exception {Class cls1 = Date.class;//cls1代表Date类在内存中的字节码Class cls2 = String.class;//cls2代表String类在内存中的字节码Class cls3 = String.class;//cls3代表String类在内存中的字节码System.out.println(cls2 == cls3);//true:同一份字节码在内存中的地址相同}4).一个类被类加载器加载到内存中,占用一片存贮空间,这个空间里的内容就是这个类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的,这一个个的空间分别用一个个的对象来表示,这些对象显然具有相同的类型,这个类型就是Class类型.5).如何得到各个字节码对应的实例对象?(Class类型):即得到字节码的三种方式:.)类名.class 例如:System.class//写程序的时候就知道类的名称.)对象.getClass() 例如:new Date().getClass().)Class.forName() 例如:Class.forName("java.util.Date");//类的字符串的完整名称做反射的时候常用第三种,因为写源程序的时候不知道类的名称,在运行的时候根据传递的字符串来创建.例如:public static void main(String[] args) throws Exception {Date nowDate = new Date();Class cls1 = nowDate.getClass();//getClass()方法返回创建该对象的字节码Class cls2 = Date.class;Class cls3 = Class.forName("java.util.Date");System.out.println(cls1);// class java.util.DateSystem.out.println(cls1 == cls2);// trueSystem.out.println(cls1 == cls3);// true//这说明三个应用变量引用的是同一份字节码}例如:public static void main(String[] args) throws Exception {Date nowDate = new Date();Date tomDate = new Date();System.out.println(nowDate == tomDate);// falseSystem.out.println(nowDate.getClass() == tomDate.getClass());// true//同一个类的字节码是相同的(即使是不同的实例对象.getClass()依然是相等的).}6)Class.forName()的作用:得到这个类的字节码,包含下面两种情况.这个类的字节码已经加载到Java虚拟机中,只需要找到返回..这个类的字节码在Java虚拟机没找到,于是用类加载器加载,然后把类的字节码缓存起来再返回..7)8个基本类型和一个void共9个预定义的Class实例对象例如:public static void main(String[] args) throws Exception {System.out.println(int.class.isPrimitive());//trueSystem.out.println(int.class == Integer.class);//falseSystem.out.println(int.class == Integer.TYPE);//true,TYPE表示基本类型 Class实例。
Java反射机制一、Java反射机制1、什么是java语言的反射机制JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2、Java反射机制主要提供了以下功能:●在运行时判断任意一个对象所属的类getClass()●在运行时构造任意一个类的对象●在运行时判断任意一个类所具有的成员变量和方法●在运行时调用任意一个对象的方法●生成jdk动态代理3、Java反射的用途Java 语言的反射机制提供了一种非常通用的动态连接程序组件的方法。
它允许你的程序创建和维护任何类的对象(服从安全限制),而不需要提前对目标类进行硬编码。
这些特征使得反射在创建与对象一同工作的类库中的通用方法方面非常有用。
例如,反射经常被用于那些数据库,XML,Eclipse或者其它的外部的框架中,如Struts,Spring,Hibernate。
初始化语句块:每创建对象new一次,都会执行;静态static初始化语句块:第一次创建new时,执行一次;之后不再执行;二、类加载机制与ClassLoader1、什么是类加载器Classloader与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序。
当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头CodeSegment(代码段)运行,负责加载Java class的这部分就叫做Class Loader。
因此Classloader也叫做类加载器。
2、Java类加载机制●类加载是动态执行的,也就是说当我们用到的时候才会去加载,如果不用的话,就不会去加载我们的类。
●类加载有两种方式:第一种就是new一个对象的时候,另一种就是当一个类的静态代码被调用的时候●静态初始化语句块在加载时只执行一次,而初始化语句块在每次new出新的对象是都会执行,等同于构造方法中的语句。
Java基础教程——反射机制Java反射机制Java反射机制是Java语⾔的⼀个重要特性,使得Java语⾔具备“动态性”:在运⾏时获取任意⼀个对象所属的类的相关信息;在运⾏时构造任意⼀个类的对象;在运⾏时获取任意⼀个类所具有的成员变量和⽅法;在运⾏时调⽤任意⼀个对象的⽅法。
JAVA反射机制是构建框架技术的基础。
例如后续学习的Spring框架等,都使⽤到反射技术;Java的反射机制依靠反射API实现,反射API主要包括以下⼏个类,后续学习:ng.Class类:代表⼀个类;ng.reflect.Field 类:类的成员变量(成员变量也称为类的属性);ng.reflect.Method类:类的⽅法;ng.reflect.Constructor 类:类的构造⽅法;ng.reflect.Array类:动态创建数组,以及访问数组的元素的静态⽅法。
通过Class实例化对象_class.newInstance()import ng.reflect.Constructor;import ng.reflect.InvocationTargetException;public class T31反射创建对象 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException,IllegalAccessException, NoSuchMethodException, SecurityException,IllegalArgumentException, InvocationTargetException {Class<?> _class = Class.forName("ng.String");// 1.直接创建对象Object newInstance = _class.newInstance();// 说明创建了⼀个空字符串:""System.out.println(newInstance.equals(""));// 2.通过获取构造⽅法,构造对象Constructor<?> _constr = _class.getConstructor(_class);Object _obj = _constr.newInstance("实例化对象");System.out.println(_obj);}}true实例化对象私有成员也能获取包括:构造,变量,⽅法getDeclaredXXX可以获取私有成员package ahjava.p07reflect;import ng.reflect.Constructor;import ng.reflect.Field;import ng.reflect.Method;public class T32获取私有成员⼀览 {public static void main(String[] args) throws Exception {// get构造⽅法();// getMethod();getField();}static void get构造⽅法() {Class<Dog> _class = Dog.class;Constructor[] _ctors = null;System.out.println("---↓↓↓getConstructors()获取public构造⽅法");_ctors = _class.getConstructors();for (Constructor c : _ctors) {System.out.println(c);}System.out.println("---↓↓↓getDeclaredConstructors()获取全部构造⽅法");_ctors = _class.getDeclaredConstructors();for (Constructor c : _ctors) {System.out.println(c);}}static void getMethod() throws NoSuchMethodException, SecurityException {Class<Dog> _class = Dog.class;Method[] mtds;System.out.println("===↓↓↓.getMethods()所有public⽅法,包括继承来的⽅法=====");mtds = _class.getMethods();for (Method md : mtds) {System.out.println(md);}System.out.println("===↓↓↓.getDeclaredMethods()所有⾃⼰声明的⽅法=====");mtds = _class.getDeclaredMethods();for (Method md : mtds) {System.out.println(md);}System.out.println("=====获取指定⽅法=====");System.out.println("-----.getMethod()只能获取public⽅法");System.out.println("-----.getDeclaredMethod()可获取private⽅法");// (⽅法名,参数类型...)Method m = _class.getDeclaredMethod("_someMethod", String.class);System.out.println(m);}static void getField()throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Class<Dog> _class = Dog.class;Field[] fields;System.out.println("=====.getFields()=====");fields = _class.getFields();for (Field fd : fields) {System.out.println(fd);}System.out.println("=====.getDeclaredFields()=====");fields = _class.getDeclaredFields();for (Field fd : fields) {System.out.println(fd);}System.out.println("=====获取指定变量=====");System.out.println("-----.getDeclaredField(...)");Field f = _class.getDeclaredField("fPrivate");System.out.println(f);}}class Dog {private Dog() {System.out.println("private构造⽅法");}public Dog(String name) {System.out.println("public构造⽅法");}public Dog(String name, int n) {System.out.println("public构造⽅法");}// -----变量-----private String fPrivate = "private变量";protected String fProtected = "protected变量";public String fPublic = "public变量";String fDefault = "未修饰变量";// -----⽅法-----private void _mPrivate() {}protected void _mProtected() {}public void _mPublic() {}void _mDefault() {}// ---private void _someMethod(String s) {}}=====.getFields()=====public ng.String ahjava.p07reflect.Dog.fPublic=====.getDeclaredFields()=====private ng.String ahjava.p07reflect.Dog.fPrivateprotected ng.String ahjava.p07reflect.Dog.fProtectedpublic ng.String ahjava.p07reflect.Dog.fPublicng.String ahjava.p07reflect.Dog.fDefault=====获取指定变量=====-----.getDeclaredField(...)private ng.String ahjava.p07reflect.Dog.fPrivate获取私有成员应⽤:import ng.reflect.Constructor;import ng.reflect.Field;import ng.reflect.Method;public class T33获取私有成员应⽤ {public static void main(String[] args) throws Exception {Class<Dog2> _class = Dog2.class;// 获取(私有)构造⽅法Constructor<Dog2> _constr = _class.getDeclaredConstructor();_constr.setAccessible(true);Object _obj = _constr.newInstance();// 获取(私有)成员变量Field _field = _class.getDeclaredField("name");_field.setAccessible(true);System.out.println("原内容:" + _field.get(_obj));_field.set(_obj, "⼆狗");// 获取(私有)⽅法(⽅法名,参数类型列表)Method m = _class.getDeclaredMethod("show", String.class, int.class); m.setAccessible(true);// __invoke:调⽤对象obj的当前⽅法,args为⽅法参数;m.invoke(_obj, "狗", 2);}}class Dog2 {private Dog2() {System.out.println("私有构造⽅法");}private String name = "SS";private void show(String str1, int n2) {System.out.println(name + ":'汪汪'" + str1 + n2);}}私有构造⽅法原内容:SS⼆狗:'汪汪'狗2。
java-反射机制txt.txt25爱是一盏灯,黑暗中照亮前行的远方;爱是一首诗,冰冷中温暖渴求的心房;爱是夏日的风,是冬日的阳,是春日的雨,是秋日的果。
反射使您的程序代码能够接入装载到JVM中的类的内部信息,允许您编写与执行时,而不是源代码中选定的类协作的代码。
这使反射成为构建灵活的应用的主要工具。
但需注意的是-- 如果使用不当,反射的成本很高。
在Java平台系列的第2部分中,软件顾问Dennis Sosnoski介绍了如何使用反射,以及某些相关的成本。
您还将找到Java Reflection API如何使您能够在运行时关联对象。
在“Java 编程的动态性,第1部分,”我为您介绍了Java编程类和类装入。
该篇文章介绍了一些Java二进制类格式的相关信息。
这个月我将阐述使用Java反射API来在运行时接入和使用一些相同信息的基础。
为了使已经熟知反射基础的开发人员关注本文,我将在文章中包括反射性能如何与直接接入相比较。
使用反射不同于常规的Java编程,其中它与元数据--描述其它数据的数据协作。
Java语言反射接入的特殊类型的原数据是JVM中类和对象的描述。
反射使您能够运行时接入广泛的类信息。
它甚至使您能够读写字段,调用运行时选择的类的方法。
反射是一种强大的工具。
它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。
但反射的某些方面存在一些疑问。
在本文中,我将深入讨论为什么您可能不希望在程序中使用反射,以及您应该这样做的理由。
在了解了权衡性分析之后,您可以自行决定是否利大于弊。
初学者的类使用反射的启点总是ng.Class实例。
如果您希望与预先定义的类协作,那么Java语言提供一种直接获得Class实例的简便快捷方式:第1部分,“类和类装入”代码:Class clas = MyClass.class;当您使用这一项技术时,装入类涉及的所有工作在幕后进行。
但是,如果您需要在运行时从某些外部源读取类名,这种方法并不适合。
JAVA基础--JAVA中的反射机制详解发布时间:2007.09.25 04:42 来源:赛迪网技术社区作者:baoclJAVA反射机制JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
1. 得到某个对象的属性1 public Object getProperty(Object owner, String fieldName) throws Exception {2 Class ownerClass = owner.getClass();34 Field field = ownerClass.getField(fieldName);56 Object property = field.get(owner);8 return property;9 }Class ownerClass = owner.getClass():得到该对象的Class。
Field field = ownerClass.getField(fieldName):通过Class得到类声明的属性。
Object property = field.get(owner):通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。
2. 得到某个类的静态属性1 public Object getStaticProperty(String className, String fieldName)2 throws Exception {3 Class ownerClass = Class.forName(className);45 Field field = ownerClass.getField(fieldName);67 Object property = field.get(ownerClass);89 return property;Class ownerClass = Class.forName(className) :首先得到这个类的Class。
java反射机制原理详解Java反射机制是指在Java语言的运行时期可以检查、操作自己的程序结构和内部数据状态的机制,它可以在加载或运行Java程序时,发现和使用程序中的类、接口、构造器、方法等对象来实现运行时的特定操作。
一、Java反射原理1、运行时提供反射机制在Java中,类将在运行时编译成字节码,在运行期间就会被CLR(Common Language Runtime)把字节码翻译成机器指令处理。
因此,Java虚拟机系统是一个能在堆内存中动态加载类、执行类中的方法、创建实例对象的运行环境,并且它是能对对象提供反射机制的可执行环境。
2.Java类提供反射机制Java类定义了一些工具类,用来提供反射机制,其中包括Class, Field, Method等类,它们都存储在ng.reflect包中,并且可以用其中的方法或API在运行时执行操作。
Class类是Java反射机制提供的重要工具,它标识一个类型在JVM(Java虚拟机)当中所对应的实例,可以通过构造函数或者类的class属性来获取Class类实例,我们可以用它来做一个触发类,用来访问类的结构,他的字节码,方法等等。
Field类提供一个 get() 方法,用来获取指定对象中的具体域的值,并有几个参数,比如:可以指定是否忽略访问权限限制。
Method类的一个 invoke() 方法,可以调用某个对象的特定方法,并接收参数作为它的返回值。
Constructor类表示一个构造函数。
它也定义了一个invoke() 方法,可以通过调用它来实例化一个对象。
二、 Java反射机制应用1、框架设计由于Java反射机制可以在运行时加载类,使得在程序运行时可以根据某种特定要求来加载对象,这对框架设计可以大有裨益,特别是像Velocity这样的模板引擎,重构后的加载模板时可以采用反射技术动态加载指定的模板类。
2、动态代理动态代理是一种常用的AOP手段,在动态代理中Java反射机制可以用来解耦代理类和被代理类,可以在不知道具体功能实现的情况下实现对代理类对应对象的操作。
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。
这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。
它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射机制的语言。
最近,反射机制也被应用到了视窗系统、操作系统和文件系统中。
反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学赋予了反射概念新的含义,但是,从现象上来说,它们确实有某些相通之处,这些有助于我们的理解。
在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。
也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
可以看出,同一般的反射概念相比,计算机科学领域的反射不单单指反射本身,还包括对反射结果所采取的措施。
所有采用反射机制的系统(即反射系统)都希望使系统的实现更开放。
可以说,实现了反射机制的系统都具有开放性,但具有开放性的系统并不一定采用了反射机制,开放性是反射系统的必要条件。
一般来说,反射系统除了满足开放性条件外还必须满足原因连接(Causally-connected)。
所谓原因连接是指对反射系统自描述的改变能够立即反映到系统底层的实际状态和行为上的情况,反之亦然。
开放性和原因连接是反射系统的两大基本要素。
Java中,反射是一种强大的工具。
它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。
反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码。
这使反射成为构建灵活的应用的主要工具。
但需注意的是:如果使用不当,反射的成本很高。
二、Java中的类反射:Reflection 是Java 程序开发语言的特征之一,它允许运行中的Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。
Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。
例如,Pascal、C 或者C++ 中就没有办法在程序中获得函数定义相关的信息。
1.检测类:1.1 reflection的工作机制考虑下面这个简单的例子,让我们看看reflection 是如何工作的。
import ng.reflect.*;public class DumpMethods {public static void main(String args[]) {try {Class c = Class.forName(args[0]);Method m[] = c.getDeclaredMethods();for (int i = 0; i < m.length; i++)System.out.println(m[i].toString());} catch (Throwable e) {System.err.println(e);}}}按如下语句执行:java DumpMethods java.util.Stack它的结果输出为:public ng.Object java.util.Stack.push(ng.Object)public synchronized ng.Object java.util.Stack.pop()public synchronized ng.Object java.util.Stack.peek()public boolean java.util.Stack.empty()public synchronized int java.util.Stack.search(ng.Object)这样就列出了java.util.Stack 类的各方法名以及它们的限制符和返回类型。
这个程序使用Class.forName 载入指定的类,然后调用getDeclaredMethods 来获取这个类中定义了的方法列表。
ng.reflect.Methods 是用来描述某个类中单个方法的一个类。
1.2 Java类反射中的主要方法对于以下三类组件中的任何一类来说-- 构造函数、字段和方法-- ng.Class 提供四种独立的反射调用,以不同的方式来获得信息。
调用都遵循一种标准格式。
以下是用于查找构造函数的一组反射调用:l Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,l Constructor[] getConstructors() -- 获得类的所有公共构造函数l Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关)l Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关)获得字段信息的Class 反射调用不同于那些用于接入构造函数的调用,在参数类型数组中使用了字段名:l Field getField(String name) -- 获得命名的公共字段l Field[] getFields() -- 获得类的所有公共字段l Field getDeclaredField(String name) -- 获得类声明的命名的字段l Field[] getDeclaredFields() -- 获得类声明的所有字段用于获得方法信息函数:l Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法l Method[] getMethods() -- 获得类的所有公共方法l Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法l Method[] getDeclaredMethods() -- 获得类声明的所有方法1.3开始使用Reflection:用于reflection 的类,如Method,可以在ng.relfect 包中找到。
使用这些类的时候必须要遵循三个步骤:第一步是获得你想操作的类的ng.Class 对象。
在运行中的Java 程序中,用ng.Class 类来描述类和接口等。
下面就是获得一个Class 对象的方法之一:Class c = Class.forName("ng.String");这条语句得到一个String 类的类对象。
还有另一种方法,如下面的语句:Class c = int.class;或者Class c = Integer.TYPE;它们可获得基本类型的类信息。
其中后一种方法中访问的是基本类型的封装类(如Integer) 中预先定义好的TYPE 字段。
第二步是调用诸如getDeclaredMethods 的方法,以取得该类中定义的所有方法的列表。
一旦取得这个信息,就可以进行第三步了——使用reflection API 来操作这些信息,如下面这段代码:Class c = Class.forName("ng.String");Method m[] = c.getDeclaredMethods();System.out.println(m[0].toString());它将以文本方式打印出String 中定义的第一个方法的原型。
2.处理对象:如果要作一个开发工具像debugger之类的,你必须能发现filed values,以下是三个步骤:a.创建一个Class对象b.通过getField 创建一个Field对象c.调用Field.getXXX(Object)方法(XXX是Int,Float等,如果是对象就省略;Object是指实例).例如:import ng.reflect.*;import java.awt.*;class SampleGet {public static void main(String[] args) {Rectangle r = new Rectangle(100, 325);printHeight(r);}static void printHeight(Rectangle r) {Field heightField;Integer heightValue;Class c = r.getClass();try {heightField = c.getField("height");heightValue = (Integer) heightField.get(r);System.out.println("Height: " + heightValue.toString());} catch (NoSuchFieldException e) {System.out.println(e);} catch (SecurityException e) {System.out.println(e);} catch (IllegalAccessException e) {System.out.println(e);}}}三、安全性和反射:在处理反射时安全性是一个较复杂的问题。
反射经常由框架型代码使用,由于这一点,我们可能希望框架能够全面接入代码,无需考虑常规的接入限制。
但是,在其它情况下,不受控制的接入会带来严重的安全性风险,例如当代码在不值得信任的代码共享的环境中运行时。
由于这些互相矛盾的需求,Java编程语言定义一种多级别方法来处理反射的安全性。
基本模式是对反射实施与应用于源代码接入相同的限制:n 从任意位置到类公共组件的接入n 类自身外部无任何到私有组件的接入n 受保护和打包(缺省接入)组件的有限接入不过至少有些时候,围绕这些限制还有一种简单的方法。
我们可以在我们所写的类中,扩展一个普通的基本类ng.reflect.AccessibleObject 类。
这个类定义了一种setAccessible方法,使我们能够启动或关闭对这些类中其中一个类的实例的接入检测。
唯一的问题在于如果使用了安全性管理器,它将检测正在关闭接入检测的代码是否许可了这样做。
如果未许可,安全性管理器抛出一个例外。
下面是一段程序,在TwoString 类的一个实例上使用反射来显示安全性正在运行:public class ReflectSecurity {public static void main(String[] args) {try {TwoString ts = new TwoString("a", "b");Field field = clas.getDeclaredField("m_s1");// field.setAccessible(true);System.out.println("Retrieved value is " +field.get(inst));} catch (Exception ex) {ex.printStackTrace(System.out);}}}如果我们编译这一程序时,不使用任何特定参数直接从命令行运行,它将在field .get(inst)调用中抛出一个IllegalAccessException异常。