Java中类反射机制基本原理

合集下载

java反射调用list参数的方法

java反射调用list参数的方法

java反射调用list参数的方法Java反射是一种强大的机制,它允许程序在运行时动态地获取类的信息并调用其方法。

本文将以Java反射调用带有List参数的方法为主题,详细介绍反射的基本原理和使用方法。

一、什么是Java反射?Java反射是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,并且对于任意一个对象,都能够调用它的任意方法。

反射使得我们可以在运行时动态地创建对象、调用方法和访问属性,极大地提高了程序的灵活性和扩展性。

二、反射的基本原理在Java中,每个类都有一个对应的Class对象,通过这个Class对象可以获取类的所有信息。

可以通过以下几种方式获取Class对象:1. 调用对象的getClass()方法;2. 通过类名.class获取;3. 使用Class.forName()方法。

三、使用反射调用List参数的方法假设我们有一个类Person,其中有一个方法public void setHobbies(List<String> hobbies),现在我们要使用反射调用这个方法。

1. 获取Class对象我们需要获取Person类的Class对象,可以使用以下方式之一:```javaClass<Person> personClass = Person.class;Class<?> personClass = Class.forName("com.example.Person");Person person = new Person();Class<? extends Person> personClass = person.getClass();```2. 获取Method对象通过Class对象,可以获取类中的方法。

我们可以使用getMethod()方法获取指定方法的Method对象,如下:```javaMethod setHobbiesMethod = personClass.getMethod("setHobbies", List.class);```3. 创建对象和参数在调用方法之前,我们需要创建Person对象和List参数,如下:```javaPerson person = new Person();List<String> hobbies = new ArrayList<>();hobbies.add("reading");hobbies.add("swimming");```4. 调用方法我们可以使用Method对象的invoke()方法来调用方法,如下:```javasetHobbiesMethod.invoke(person, hobbies);```通过以上步骤,我们成功地使用反射调用了带有List参数的方法。

Java反射,获取类的公有、私有的构造函数(有参,无参)、方法(有参,无参)、属性

Java反射,获取类的公有、私有的构造函数(有参,无参)、方法(有参,无参)、属性

Java反射,获取类的公有、私有的构造函数(有参,⽆参)、⽅法(有参,⽆参)、属性Class类与ng.reflect类库⼀起对反射进⾏了⽀持,该类库包含Field、Method和Constructor类,这些类的对象由JVM在启动时创建,⽤以表⽰未知类⾥对应的成员。

这样的话就可以使⽤Contructor创建新的对象,⽤get()和set()⽅法获取和修改类中与Field对象关联的字段,⽤invoke()⽅法调⽤与Method对象关联的⽅法。

另外,还可以调⽤getFields()、getMethods()和getConstructors()等许多便利的⽅法,以返回表⽰字段、⽅法、以及构造器对象的数组,这样,对象信息可以在运⾏时被完全确定下来,⽽在编译时不需要知道关于类的任何事情。

⾸先创建⼀个类1public class Per {2public String name="sunshine";3private int age=28;4public double weight=65.50;56public Per(){7 System.out.println("测试反射获取公有⽆参构造函数");8 }9private Per(String name){=name;11 System.out.println("测试反射获取私有有参构造函数");12 }13public Per(String name,int age){=name;15this.age=age;16 System.out.println("测试反射获取公有有多个参数构造函数name:"+name+" age:"+age);17 }18public String methodT1(){19 System.out.println("测试反射获取公有⽆参⽅法");20return null;21 }22public String methodT1(String name,int age){23 System.out.println("测试反射获取公有多个参⽅法");24 System.out.println(name+":"+age);25return null;26 }27private String methodT1(String name){28 System.out.println("测试反射获取私有有参⽅法");29 System.out.println("name:"+name);30return null;31 }32public String methodT2(int[] arr,String[] str){33 System.out.println("测试反射获取公有有数组参⽅法");34 System.out.println("int[] arr:"+arr+"String[] str:"+str);35return null;36 }37public static void main(String[] args) {38 System.out.println("测试反射获取main⽅法");39 }40 }1.使⽤java反射获取类的构造函数(公有、私有)(有参,⽆参)1import ng.reflect.Constructor;2import ng.reflect.Field;3import ng.reflect.Method;45import org.junit.AfterClass;6import org.junit.BeforeClass;7import org.junit.Test;8/**9 * 测试使⽤java反射获取类的构造函数并创建对象10 * @author Sunshine11 *12*/13public class ReflectPer {14private static Class class1;15//因为java反射获取类时都需要加载类,在这⾥我就使⽤Junit的@beforeclass来去加载类,不⽤在每个测试⽅法中重复创建16//注:@beforeclass在执⾏测试⽅法前运⾏17 @BeforeClass18public static void beforeClass() throws Exception{19 System.out.println("====测试⽅法启动前先加载类====");20 class1 = Class.forName("myPractise.Per");//加载类21 }22//获取类的公有⽆参构造函数,并创建对象23 @Test24public void test1() throws Exception{25 Constructor constructor = class1.getConstructor(null);//获取公有⽆参构造器,值为null代表获取⽆参构造器26 Per per = (Per) constructor.newInstance(null);//创建对象,返回的是Object类型要强转27 System.out.println();//可以调⽤类的属性-----成功28 }29//获取类的公有参构造函数,并创建对象30 @Test31public void test2()throws Exception{32 Constructor constructor = class1.getConstructor(String.class,int.class);//获取公有多个参数构造器,参数为构造器中参数的类型33 Per per = (Per)constructor.newInstance("baby",24);//创建对象34 }35//获取类的私有有参构造函数,并创建对象36 @Test37public void test3()throws Exception{38 Constructor constructor = class1.getDeclaredConstructor(String.class);//获取公有多个参数构造器,参数为构造器中参数的类型39 constructor.setAccessible(true);//暴⼒反射,只有将属性设置为true才可以创建对象40 Per per = (Per)constructor.newInstance("baby");41 System.out.println(per.weight);//可以调⽤类的属性-----成功42//注:通常情况下⼀个类不可以访问另⼀个类的私有的属性,⽅法。

反射机制的方法

反射机制的方法

反射机制的方法反射机制是一种在编程中常用的技术,它允许程序在运行时动态地获取类的信息并操作对象。

通过反射机制,我们可以在不知道具体类的情况下调用其方法、访问其字段以及创建对象实例。

本文将介绍反射机制的原理、应用场景以及注意事项。

一、反射机制的原理反射机制是基于Java的反射API实现的,主要涉及到以下几个核心类:Class、Constructor、Field和Method。

通过这些类,我们可以获取类的信息并进行相应的操作。

1. Class类:表示类的实体,在程序运行时,JVM会为每个类加载对应的Class对象。

通过Class对象,我们可以获取类的构造方法、字段和方法等信息。

2. Constructor类:表示类的构造方法。

通过Constructor类,我们可以创建对象实例。

3. Field类:表示类的字段。

通过Field类,我们可以获取和设置字段的值。

4. Method类:表示类的方法。

通过Method类,我们可以调用类的方法。

反射机制的原理就是通过这些类来获取和操作类的信息,从而实现动态地调用方法、访问字段和创建对象实例。

二、反射机制的应用场景反射机制在实际开发中有着广泛的应用场景,下面列举几个常见的应用场景。

1. 框架设计:许多框架都使用了反射机制来实现插件化的功能。

通过反射,框架可以动态地加载插件并调用其方法。

2. 单元测试:在单元测试中,我们常常需要对私有方法进行测试。

通过反射,我们可以获取私有方法并调用它们,从而实现对私有方法的测试。

3. 动态代理:动态代理是Java中的一种常见设计模式,它可以在运行时动态地生成代理类。

通过反射,我们可以获取类的方法并在代理方法中进行调用。

4. 序列化与反序列化:在将对象存储到文件或者通过网络传输时,我们需要将对象转换为字节流或者字符流。

通过反射,我们可以获取类的字段并将其转换为字节流或者字符流。

三、反射机制的注意事项虽然反射机制在某些情况下非常有用,但是在使用时也需要注意一些问题。

Java泛型和反射机制

Java泛型和反射机制
GenericsFoo douFoo=new GenericsFoo(new Double("33"));
实际上,当构造对象时不指定类型信息的时候,默认会使用 实际上,当构造对象时不指定类型信息的时候,默认会使用Object类 类 这也是要强制转换的原因。 型,这也是要强制转换的原因。
Java泛型:有界类型 泛型: 泛型
GenericsFoo<Double> douFoo=new GenericsFoo<Double>(new Double("33"));
当然, 当然,也可以在构造对象的时候不使用尖括号指定泛型类型的真实类 但是你在使用该对象的时候,就需要强制转换了。比如: 型,但是你在使用该对象的时候,就需要强制转换了。比如:
Java泛型:泛型类语法 泛型: 泛型
泛型类的语法说明: 泛型类的语法说明: 使用<T>来声明一个类型持有者名称,就可以把 当作一个类型代表 来声明一个类型持有者名称 使用 来声明一个类型持有者名称,就可以把T当作一个类型代表 来声明成员、参数和返回值类型。 仅仅是个名字 这个名字可以自定义。 仅仅是个名字, 来声明成员、参数和返回值类a泛型:泛型方法 泛型: 泛型
是否拥有泛型方法,与其所在的类是否泛型没有关系。要定义泛型方法, 是否拥有泛型方法,与其所在的类是否泛型没有关系。要定义泛型方法, 只需将泛型参数列表置于返回值前。 只需将泛型参数列表置于返回值前。如: public class ExampleA { public <T> void f(T x) { System.out.println(x.getClass().getName()); } } 使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。 使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。泛 型方法除了定义不同,调用就像普通方法一样。 型方法除了定义不同,调用就像普通方法一样。

java反射获取field 类型

java反射获取field 类型

java反射获取field 类型如何在Java中使用反射来获取字段类型和数组类型。

一、引言Java中的反射机制允许我们在运行时动态地获取和操作类的属性和方法。

在某些情况下,我们可能需要获取类中字段的具体类型,尤其是在处理数组数据时。

本文将介绍如何使用Java的反射机制来获取字段类型和数组类型。

二、什么是反射反射是指程序在运行时可以获取自身的信息,并且可以对自身的属性和方法进行操作。

Java的反射API提供了一组类和接口,可以让我们在运行时分析和操作类、接口、方法、字段等。

三、通过反射获取字段类型要通过反射获取字段的类型,我们首先需要获取类的Class对象。

Class对象是Java反射API中最重要的类之一,它代表了运行时类的类型信息。

我们可以通过以下方式获取一个类的Class对象:1. 使用“类名.class”语法获取:Class clazz = MyClass.class;2. 使用“对象.getClass()”方法获取:MyClass instance = new MyClass();Class clazz = instance.getClass();3. 使用“Class.forName()”方法获取:Class clazz = Class.forName("com.example.MyClass");获取Class对象之后,我们就可以通过Field对象的getType()方法获取字段的类型。

Field对象表示类的字段,可以通过Class对象的getDeclaredField()方法获取具体的Field对象。

下面是一个示例代码,演示了如何通过反射获取字段类型:javaclass MyClass {private String name;public int age;}public class Main {public static void main(String[] args) throws Exception {Class clazz = MyClass.class;Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {System.out.println(field.getName() + ": " +field.getType().getName());}}}输出结果为:name: ng.Stringage: int四、通过反射获取数组类型在Java中,数组是一种特殊的对象,也可以通过反射来获取其类型信息。

java反射机制的原理

java反射机制的原理

Java反射机制的原理在Java运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。

对于任意一个对象,可以调用它的任意一个方法。

这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。

Java 反射机制主要提供了以下功能在运行时判断任意一个对象所属的类。

在运行时构造任意一个类的对象。

在运行时判断任意一个类所具有的成员变量和方法。

在运行时调用任意一个对象的方法关于JA V A更多反射机制的资料以及跟高手学习机会,可以加到群422,然后就是912,加上最后的489,感觉还不错。

现在才开始学反射机制没多久,差不多已经把这一块搞清楚了反射的常用类和函数:Java反射机制的实现要借助于4个类:Class,Constructor,Field,Method;其中class代表的是类对象,Constructor -类的构造器对象,Field-类的属性对象,Method-类的方法对象,通过这四个对象我们可以粗略的看到一个类的各个组成部分。

其中最核心的就是Class类,它是实现反射的基础,它包含的方法我们在第一部分已经进行了基本的阐述。

应用反射时我们最关心的一般是一个类的构造器、属性和方法,下面我们主要介绍Class类中针对这三个元素的方法:1、得到构造器的方法Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,Constructor[] getConstructors() -- 获得类的所有公共构造函数Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关)Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关)2、获得字段信息的方法Field getField(String name) -- 获得命名的公共字段Field[] getFields() -- 获得类的所有公共字段Field getDeclaredField(String name) -- 获得类声明的命名的字段Field[] getDeclaredFields() -- 获得类声明的所有字段3、获得方法信息的方法Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法Method[] getMethods() -- 获得类的所有公共方法Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法Method[] getDeclaredMethods() -- 获得类声明的所有方法在程序开发中使用反射并结合属性文件,可以达到程序代码与配置文件相分离的目的如果我们想要得到对象的信息,一般需要“引入需要的‘包.类’的名称——通过new实例化——取得实例化对象”这样的过程。

Java反射(Class类,Class对象获取)

Java反射(Class类,Class对象获取)

Java反射(Class类,Class对象获取)⽬录Java反射超详解1.反射基础1.1Class类1.2类加载2.反射的使⽤2.1Class对象的获取2.2Constructor类及其⽤法2.3Field类及其⽤法Java反射超详解1.反射基础Java反射机制是在程序的运⾏过程中,对于任何⼀个类,都能够知道它的所有属性和⽅法;对于任意⼀个对象,都能够知道它的任意属性和⽅法,这种动态获取信息以及动态调⽤对象⽅法的功能称为Java语⾔的反射机制。

Java反射机制主要提供以下这⼏个功能:在运⾏时判断任意⼀个对象所属的类在运⾏时构造任意⼀个类的对象在运⾏时判断任意⼀个类所有的成员变量和⽅法在运⾏时调⽤任意⼀个对象的⽅法1.1Class类Class类,Class类也是⼀个实实在在的类,存在于JDK的ng包中。

Class类的实例表⽰java应⽤运⾏时的类(class ans enum)或接⼝(interface and annotation)(每个java类运⾏时都在JVM⾥表现为⼀个class对象,可通过类名.class、类型.getClass()、Class.forName("类名")等⽅法获取class对象)。

数组同样也被映射为为class 对象的⼀个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。

基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为 class 对象。

到这我们也就可以得出以下⼏点信息:Class类也是类的⼀种,与class关键字是不⼀样的。

⼿动编写的类被编译后会产⽣⼀个Class对象,其表⽰的是创建的类的类型信息,⽽且这个Class对象保存在同名.class的⽂件中(字节码⽂件)。

每个通过关键字class标识的类,在内存中有且只有⼀个与之对应的Class对象来描述其类型信息,⽆论创建多少个实例对象,其依据的都是⽤⼀个Class对象。

Java中的反射机制及其在AOP中的应用

Java中的反射机制及其在AOP中的应用

反射机制及其在Java中的应用简介反射机制是Java语言的一项重要特性,它允许程序在运行时获取一个类的信息,并通过这些信息动态地操作对象。

它提供了一种强大的能力,可以实现一些在编译时无法预知的操作。

在本文中,我们将深入探讨Java中的反射机制,并探讨其在面向切面编程(AOP)中的应用。

反射机制的基本概念类加载器在讨论反射机制之前,我们需要了解Java中的类加载器。

类加载器负责将类的字节码文件加载到内存中,并生成对应的Class对象。

Java中存在多个层次的类加载器,每个类加载器负责加载特定的类。

具体的类加载器层次结构可以用一棵树来表示,根加载器(Bootstrap Class Loader)位于树的最顶层,它加载核心类库。

其他的类加载器(如扩展类加载器、应用程序类加载器)则分别加载扩展类和应用程序类。

Class对象Class对象是反射机制的核心,它代表一个类的实例。

在Java中,每个类都有一个对应的Class对象,并且在程序运行期间只会加载一次。

通过Class对象,我们可以获取类的属性、方法和构造函数等信息,并对其进行动态操作。

反射APIJava提供了一系列的反射API,用于操作Class对象和对象实例。

这些API包括了获取类的信息、创建对象实例、调用方法和获取/设置属性等功能。

反射机制的应用动态加载类通过反射机制,我们可以在运行时动态地加载一个类。

这对于需要根据条件来选择不同的实现类的场景非常有用。

通过Class.forName()方法,我们可以根据类的全限定名来加载一个类,并获取对应的Class对象。

Class<?> clazz = Class.forName("com.example.MyClass");实例化对象反射机制可以在运行时动态地实例化一个对象。

通过Class对象的newInstance()方法,我们可以创建一个对象实例。

Class<?> clazz = MyClass.class;Object obj = clazz.newInstance();调用方法反射机制提供了强大的功能来调用对象的方法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Java中的类反射机制一、反射的概念反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。

这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。

它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

其中LEAD/LEAD++ 、Open C++ 、Meta Xa和Open Java等就是基于反射机制的语言。

最近,反射机制也被应用到了视窗系统、操作系统和文件系统中。

反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学赋予了反射概念新的含义,但是,从现象上来说,它们确实有某些相通之处,这些有助于我们的理解。

在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。

也就是说,这类应用通过采用某种机制来实现对自己行为的描述(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 提供四种独立的反射调用,以不同的方式来获得信息。

调用都遵循一种标准格式。

以下是用于查找构造函数的一组反射调用:Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,Constructor[] getConstructors() -- 获得类的所有公共构造函数Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关)Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关)获得字段信息的Class 反射调用不同于那些用于接入构造函数的调用,在参数类型数组中使用了字段名:Field getField(String name) -- 获得命名的公共字段Field[] getFields() -- 获得类的所有公共字段Field getDeclaredField(String name) -- 获得类声明的命名的字段Field[] getDeclaredFields() -- 获得类声明的所有字段用于获得方法信息函数:Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法Method[] getMethods() -- 获得类的所有公共方法Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法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编程语言定义一种多级别方法来处理反射的安全性。

基本模式是对反射实施与应用于源代码接入相同的限制:从任意位置到类公共组件的接入类自身外部无任何到私有组件的接入受保护和打包(缺省接入)组件的有限接入不过至少有些时候,围绕这些限制还有一种简单的方法。

我们可以在我们所写的类中,扩展一个普通的基本类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异常。

相关文档
最新文档