● 什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。
在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
反射是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性和方法。Java 的这一能力在实际应用中用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。
● 反射能干什么
反射是 Java 被视为动态(或准动态)语言的关键,允许程序于执行期通过 Reflection API 取得任何已知名称的class 的內部信息,包括 package、superclass、implemented interfaces、inner classes, outer class, fields、constructors、methods、modifiers,並可于执行期生成instances、变更 fields 內容或唤起 methods。
这里将示例通过反射获得class的fields,methods,constructors。其他class的信息通过Reflection API也可以反射获得。
● 如何使用反射
1. 反射的路口
使用反射的起点是 java.lang.Class 实例。如果您希望与预先定义的类协作,那么Java语言提供一种直接获得 Class 实例的简便快捷方式:
Class clas = MyClass.class;
当您使用这一项技术时,装入类涉及的所有工作在幕后进行。但是,如果您需要在运行时从某些外部源读取类名,这种方法并不适合。实际上,您需要使用一个类装入器来查找类信息。以下介绍一种方法:
// "name" is the class name to load
Class clas = null;
try {
clas = Class.forName(name);
} catch (ClassNotFoundException ex) {
// handle exception case
}
// use the loaded class
2. 反射构造函数
Class 对象为您提供接入类元数据的反射的所有基本hook。这类元数据包括类自身的信息,如包,类的父类,以及该类实施的接口。它还包括该类定义的构造函数、字段和方法的详细信息。
对于构造函数、字段和方法三类组件中的任何一类来说java.lang.Class 提供四种独立的反射调用,以不同的方式来获得信息。调用都遵循一种标准格式。以下是用于查找构造函数的一组反射调用:
Constructor getConstructor(Class[] params)-- 获得使用特殊的参数类型的公共构造函数,
Constructor[] getConstructors()-- 获得类的所有公共构造函数
Constructor getDeclaredConstructor(Class[] params)-- 获得使用特定参数类型的构造函数
Constructor[] getDeclaredConstructors()-- 获得类的所有构造函数(与接入级别无关)
每类这些调用都返回一个或多个java.lang.reflect.Constructor 函数。这种Constructor 类定义 newInstance 方法,它采用一组对象作为其唯一的参数,然后返回新创建的原始类实例。该组对象是用于构造函数调用的参数值。为了解释这一工作流程,假设您有一个 MyString 类和MyString 类中有一个使用一对String s的构造函数,如清单①所示。
清单①:定义MyString类,其中有使用两个String的构造函数。
public class MyString {
private String str1;
private String str2;
public MyString(String str1, String str2) {
this.str1 = str1;
this.str2 = str2;
}
public void print() {
System.out.println(str1);
System.out.println(str2);
}
}
清单②:使用反射获得构造函数,并调用获得的构造函数。
public class ReflectionTest {
public static void main(String[] args) {
Class myStringCla = null;
Class[] types = new Class[]{String.class, String.class};
Constructor<Object> cons = null;
MyString myString = null;
try {
myStringCla =
Class.forName("com.fujitsu.reflectioon.MyString");
cons = myStringCla.getConstructor(types);
Object[] objs = new Object[]{"haha", "reflect success"};
myString = (MyString) cons.newInstance(objs);
myString.print();
} catch (ClassNotFoundException e) {
......
控制台输出"haha reflect success",说明使用Reflection API成功反射获得MyString的构造函数,通过获得的构造函数成功创建了MyString的对象。
3. 反射字段信息
获得字段信息的Class反射调用不同于那些用于接入构造函数的调用,在参数类型数组中使用的是字段名:
Field getField(String name)-- 获得命名的公共字段
Field[] getFields()-- 获得类的所有公共字段
Field getDeclaredField(String name)-- 获得类声明的命名的字段
Field[] getDeclaredFields()-- 获得类声明的所有字段
尽管与构造函数调用类似,但是在字段方面仍存在一个重要的区别点:前两个变量返回可以通过类接入的公共字段的信息,即使它们来自于祖先类。后两个变量返回类直接声明的字段的信息,与字段的接入类型无关。
调用返回的java.lang.reflect.Field实例定义所有基本类型的 getXXX 和 setXXX 方法,以及与引用类型协作的通用get和set 法。您可以根据实际的字段类型自行选择一种适当的方法,而 getXXX 方法将自动处理扩展转换(如使用 getInt 方法来检索一个字节值)。
清单③显示使用字段反射获得MyString的str1,并修改str1字段的信息:
Field field = myStringCla.getDeclaredField("str1");
field.setAccessible(true);
Object str = field.get(myString);
str = "reflect filed success";
field.set(myString, str);
System.out.println(myString.getStr1());
控制台输出"reflect filed success",说明使用Reflection API成功反射获得MyString的字段信息,并成功修改了MyString的字段。
4. 反射方法
获得方法信息的Class反射调用与用于构造函数和字段的调用非常类似:
Method getMethod(String name, Class[] params)-- 使用特定的参数类型,获得命名的公共方法
Method[] getMethods()-- 获得类的所有公共方法
Method getDeclaredMethod(String name, Class[] params)-- 使用特写的参数类型,获得类声明的命名的方法
Method[] getDeclaredMethods()-- 获得类声明的所有方法
与字段调用一样,前两个变量返回可以通过类接入的公共方法的信息,即使它们来自于祖先类。后两个变量返回类声明的方法的信息,与方法的接入类型无关。
调用返回的java.lang.reflect.Method实例定义了一种 invoke 方法,可以用invoke 来调用被反射的Method。这种invoke方法有两个参数,为调用提供类实例和参数值数组。
清单④进一步显示反射获得MyString实例的print方法。并使用Method的invoke方法调用print方法,清单④示例如下。
Method method = myStringCla.getDeclaredMethod("print");
method.invoke(myString, null);
控制台输出" haha reflect Method success",说明使用Reflection API成功反射获得MyString的print方法,并使用Method的invoke方法调用MyString的print方法。
以上介绍了如何使用反射获得实例的构造函数,字段,方法。当然我们还可以通过反射获得实例的更多信息,这里就不一一介绍。
分享到:
相关推荐
之前上课的时候老师总结的JavaReflection反射学习资料,内容简单易懂,浅显易懂,适合小白入手学习。。
总结,Java反射机制是其强大之处,它为开发者提供了超越静态类型系统的灵活性。然而,也应谨慎使用,避免滥用反射导致的性能下降和潜在的安全隐患。通过阅读"JAVA私塾笔记整理——反射机制(Reflection)",你可以更...
### Java反射机制详解 #### 一、Java反射机制概述 反射是Java编程语言的一个关键特性,它赋予了Java程序在运行时自我检查的能力,并...通过本文的学习,希望能够帮助大家更好地理解和运用反射这一重要的Java特性。
无论是对于初学者还是有经验的开发者来说,本书都是学习和掌握Java反射技术不可或缺的宝贵资源。通过阅读本书,不仅可以提高对Java反射的理解,还能激发新的创意和灵感,将反射技术应用于更多创新的场景之中。
《Java反射技术实战》这本书由Ira R. Forman和Nate Forman撰写,由Manning出版社出版,是一本深入探讨Java反射技术的...这本书不仅提供了清晰的指导,还激发了创意和乐趣,使得反射的学习过程既富有成效又充满乐趣。
这份"Java学习大总结.pdf"文档涵盖了Java的核心概念,包括数据类型、排序算法以及类的定义和成员,这些都是Java编程的基础。 在第一章“数据类型”中,Java提供了两种主要的数据类型:基本类型(Primitive Types)...
《领域驱动设计(DDD)学习总结与反思》 在深入学习领域驱动设计(Domain-Driven Design,简称DDD)的过程中,我积累了一些宝贵的经验和感悟,这些都收录在"ddd-summary-and-reflection-master.zip"文件中。DDD作为...
总结来说,"HTML-CSS-Reflection"项目是一个学习和实践HTML和CSS的好机会,特别是关于页面结构、布局设计和响应式技术的运用。通过此项目,你可以提升自己的网页设计能力,同时对HTML5和CSS3有更深入的理解。
暑期眼镜店打工实习总结是一个非常有价值的学习和工作经验总结,它可以帮助我们更好地总结和分析自己的学习和工作经验,锻炼我们的语言组织能力和写作能力。下面是暑期眼镜店打工实习总结的知识点: 1. importance ...
以下是对"Java零基础小白学习重点难点总结【老杜】"的详细解读: 1. **基础语法**: - 变量与数据类型:Java支持基本数据类型(如int、double、boolean等)和引用类型(如类、接口和数组)。理解它们的区别和用法...
#### 六、总结 《Java反射技术实战》这本书不仅详细介绍了Java反射技术的核心概念和应用场景,还提供了丰富的示例代码来帮助读者理解如何正确地使用反射技术解决实际问题。无论是初学者还是经验丰富的开发者,都...
【接口学习总结】 接口在Java中是一种完全抽象的类,不包含任何实现。它定义了一组方法签名,实现了接口的类必须实现这些方法。接口是多继承的唯一途径,一个类可以实现多个接口,从而实现多重抽象行为。Java 8引入...
在Java编程语言中,反射(Reflection)是一种强大的工具,它允许程序在运行时检查和操作类、接口、字段和方法的信息。JavaBeans包(java.beans)提供了与JavaBeans组件交互的相关类和接口,这些组件是Java面向对象...
总结,本项目“rt.rar_Transmission_optics_reflection”提供的MATLAB实现,是对光学中反射与透射现象的数值模拟,通过对不同参数的调整,可以深入理解光在各种条件下的行为,并为实际光学设计和实验提供理论依据。...
在IT行业中,反射(Reflection)是一项强大的编程特性,它允许程序在运行时检查自身的行为和属性,甚至...在"Reflection_weekly:系统梳理总结"的学习过程中,我们可以不断探索这些可能性,进一步提高我们的IT技能。
2. 反思神经网络(Reflection Neural Network):反思神经网络是一种特殊的神经网络结构,它可以帮助我们对模型的学习过程和结果进行审视、分析和总结。 结论: 深度学习作为领域的一个重要分支,已经得到了广泛的...
总结,Java反射和注解是Java世界中的重要概念,它们为程序员提供了强大的工具,帮助实现灵活、动态和元数据驱动的编程。学习和掌握这两者,对于提升Java开发者的技能水平和解决复杂问题的能力至关重要。通过“浙大...
《Java反射技术实战》这本书由Ira R. Forman和Nate Forman撰写,由MANNING...通过阅读本书,开发者能够掌握反射的核心概念,学习到各种实用的技巧,并能将这些知识应用于自己的项目中,提升软件的灵活性和可扩展性。