Java反射机制(Reflection)
Java反射机制(Reflection)
一、反射机制是什么
Java反射机制是程序在运行过程中,对于任意一个类都能够知道这个类的所有属性和方法;对于任意一个对象都能够调用它的任意一个方法和属性,这种动态获取类信息以及动态调用对象方法的功能就是JAVA语言的反射机制。
二、反射机制能干什么
(1)在运行时判断任意一个对象所属的类
(2)在运行时构造任意一个类的对象
(3)在运行时判断任意一个类所具有的成员变量和方法
(4)在运行时调用任意一个对象的方法
(PS:注意反射机制都是在程序运行时,而不是在编译时。)
反射机制允许程序在运行时透过JDK提供的反射API获取任意一个已知名称的class的内部消息,包括: 修饰符、父类、接口、属性、构造方法、方法 等所有的信息,并可在程序运行时改变属性的值或者调用方法。
三、JDK提供的反射机制中的类
在JDK中主要由以下类来实现Java的反射机制,这些类都位于java.lang.reflect包中(Class类除外):
java.lang.Class: 代表一个类
java.lang.reflect.Constructor:代表类的构造方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Modifier:代表修饰符
java.lang.reflect.Array:提供动态创建数组,以及访问数组的元素的静态方法
四、利用示例对反射机制的使用进行初步体会
示例一:
利用反射机制打印java.lang.String类中所有的属性、构造方法、方法
/**
*利用反射机制打印String类中的所方法信息
* @author Administrator
*
*/
public class ObjectReflectDemo {
public static void main(String[] args) throws Exception {
//反射的第一步是获取要操作的类所对应的Class对象
Class<?> cls = Class.forName("java.lang.String");
System.out.println("---------String类中的属性:---------------------"); Field[] fields = cls.getDeclaredFields();
for(Field f : fields){
System.out.println(f);
}
System.out.println("---------String类中的构造方法:--------------------");
Constructor[] contructors = cls.getDeclaredConstructors();
for(Constructor c : contructors){
System.out.println(c);
}
System.out.println("---------String类中的方法:---------------------");
Method[] methods = cls.getDeclaredMethods();
for(Method m : methods){
System.out.println(m);
}
}
}
运行结果:
---------String类中的属性:---------------------
private final char[] java.lang.String.value
private int java.lang.String.hash
private static final long java.lang.String.serialVersionUID
private static final java.io.ObjectStreamField[] java.lang.String.serialPersistentFields
public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER
private static final int java.lang.String.HASHING_SEED
private transient int java.lang.String.hash32
---------String类中的构造方法:--------------------
public java.lang.String(byte[])
public java.lang.String(byte[],int,int)
public java.lang.String(byte[],java.nio.charset.Charset)
public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int,int,java.nio.charset.Charset)
java.lang.String(int,int,char[])
java.lang.String(char[],boolean)
public java.lang.String(java.lang.StringBuilder)
public java.lang.String(java.lang.StringBuffer)
public java.lang.String(int[],int,int)
public java.lang.String(char[],int,int)
public java.lang.String(char[])
public java.lang.String(java.lang.String)
public java.lang.String()
public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int)
public java.lang.String(byte[],int,int,int)
---------String类中的方法:---------------------
public boolean java.lang.String.equals(java.lang.Object)
public java.lang.String java.lang.String.toString()
public int java.lang.String.hashCode()
public int java.lang.String.compareTo(java.lang.String)
public int java.lang.String.compareTo(java.lang.Object)
public int java.lang.String.indexOf(int)
public int java.lang.String.indexOf(java.lang.String,int)
public int java.lang.String.indexOf(java.lang.String)
public int java.lang.String.indexOf(int,int)
static int java.lang.String.indexOf(char[],int,int,char[],int,int,int)
public static java.lang.String java.lang.String.valueOf(double)
public static java.lang.String java.lang.String.valueOf(char[],int,int)
public static java.lang.String java.lang.String.valueOf(float)
public static java.lang.String java.lang.String.valueOf(java.lang.Object)
public static java.lang.String java.lang.String.valueOf(long)
public static java.lang.String java.lang.String.valueOf(char[])
public static java.lang.String java.lang.String.valueOf(boolean)
public static java.lang.String java.lang.String.valueOf(char)
public static java.lang.String java.lang.String.valueOf(int)
public char java.lang.String.charAt(int)
private static void java.lang.String.checkBounds(byte[],int,int)
public int java.lang.String.codePointAt(int)
public java.lang.String java.lang.String.concat(java.lang.String)
public boolean java.lang.String.contains(java.lang.CharSequence)
public static java.lang.String java.lang.String.copyValueOf(char[])
public static java.lang.String java.lang.String.copyValueOf(char[],int,int)
public boolean java.lang.String.endsWith(java.lang.String)
public static java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[])
public static java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[])
public byte[] java.lang.String.getBytes()
public byte[] java.lang.String.getBytes(java.nio.charset.Charset)
public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException
public void java.lang.String.getBytes(int,int,byte[],int)
public void java.lang.String.getChars(int,int,char[],int)
void java.lang.String.getChars(char[],int)
public int java.lang.String.codePointBefore(int)
public int java.lang.String.codePointCount(int,int)
public int java.lang.String.compareToIgnoreCase(java.lang.String)
public boolean java.lang.String.contentEquals(java.lang.CharSequence)
public boolean java.lang.String.contentEquals(java.lang.StringBuffer)
public boolean java.lang.String.equalsIgnoreCase(java.lang.String)
private int java.lang.String.indexOfSupplementary(int,int)
private int java.lang.String.lastIndexOfSupplementary(int,int)
public int java.lang.String.offsetByCodePoints(int,int)
int java.lang.String.hash32()
public native java.lang.String java.lang.String.intern()
public boolean java.lang.String.isEmpty()
public int java.lang.String.lastIndexOf(java.lang.String,int)
static int java.lang.String.lastIndexOf(char[],int,int,char[],int,int,int)
public int java.lang.String.lastIndexOf(int,int)
public int java.lang.String.lastIndexOf(int)
public int java.lang.String.lastIndexOf(java.lang.String)
public int java.lang.String.length()
public boolean java.lang.String.matches(java.lang.String)
public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence)
public java.lang.String java.lang.String.replace(char,char)
public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String)
public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String)
public java.lang.String[] java.lang.String.split(java.lang.String,int)
public java.lang.String[] java.lang.String.split(java.lang.String)
public boolean java.lang.String.startsWith(java.lang.String)
public boolean java.lang.String.startsWith(java.lang.String,int)
public java.lang.CharSequence java.lang.String.subSequence(int,int)
public java.lang.String java.lang.String.substring(int)
public java.lang.String java.lang.String.substring(int,int)
public char[] java.lang.String.toCharArray()
public java.lang.String java.lang.String.toLowerCase(java.util.Locale)
public java.lang.String java.lang.String.toLowerCase()
public java.lang.String java.lang.String.toUpperCase(java.util.Locale)
public java.lang.String java.lang.String.toUpperCase()
public java.lang.String java.lang.String.trim()
public boolean java.lang.String.regionMatches(int,java.lang.String,int,int)
public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int)
从上面示例中可以看出,要想使用反射的第一步就是获取要操作类所对应的Class对象,一共有三种方法:
第一种: 调用Class类的静态方法forName,比如 Class.forName("java.lang.String")
第二种: 使用类的.class语法,比如 : Class cls = String.class
第三种: 调用对象的getClass方法, 比如:String str = "123"; Class cls = str.getClass();(PS:在java.lang.Object类中定义了getClass()方法,因此对于任意一个Java对象,都可以通过此方法获得对象的类型)
示例二:
import java.lang.reflect.Field;
import java.lang.reflect.Method; /**
* 要求:
* 1.通过反射的方式调用add方法
* 2.通过反射的方式调用getNum方法
* 3.通过反射的反射修改num属性的值为55,再通过反射的方式调用getNum方法
* @author Administrator
*
*/
public class ReflectTest {
private int num = 2; public int add(int a,int b){
return a+b;
} public int getNum() {
return num;
} public static void main(String[] args) throws Exception {
//第一步: 获取ReflectTest类所对应的Class对象
Class<?> cls = Class.forName("ReflectTest");
//第二步:通过Class类的newInstance()方法来创建ReflectTest类的一个对象
Object obj = cls.newInstance(); //第步:通过Class的getDeclaredMethod(String name, Class<?>... parameterTypes)获取ReflectTest类中指定的方法
Method addMethod = cls.getDeclaredMethod("add", new Class[]{int.class,int.class});
Method getNumMethod = cls.getDeclaredMethod("getNum", new Class[]{}); //第四部:通过Method类的invoke(Object obj, Object... args)方法来反射调用ReflectTest类中指定的方法
//4.1通过反射调用add方法
int addResult = (int)addMethod.invoke(obj, new Object[]{11,22});
System.out.println("addResult = " + addResult); //4.2通过反射的方式调用getNum方法
int returnNum1 = (int)getNumMethod.invoke(obj, new Object[]{});
System.out.println("returnNum1 = " + returnNum1); //4.3通过反射的反射修改num属性的值为55,再通过反射的方式调用getNum方法
Field field = cls.getDeclaredField("num");
field.set(obj, 55);
int returnNum2 = (int)getNumMethod.invoke(obj, new Object[]{});
System.out.println("returnNum2 = " + returnNum2);
}
}
通过上面的2个示例,可以看出:
(1)反射的第一步是获取要操作的类所对应的Class对象(有三种方式)
(2)类中每一个方法对应着一个java.lang.reflect.Method对象
(3)类中每一个属性对应着一个java.lang.reflect.Field对象
五、使用java反射机制,需要遵循的三步
第一步:获取要操作的类所对应的Class对象,得到该Class对象后就可以获取想要操作类的所有信息。(具体参考java.lang.Class API)
第二步: 通过Class对象去获取操作类的属性、构造方法、方法 所分别对应的Field、Constructor、Method的对象
第三步: 调用Field、Constructor、Method对象中的方法
Java反射机制(Reflection)的更多相关文章
- Java - 反射机制(Reflection)
Java - 反射机制(Reflection) > Reflection 是被视为 动态语言的关键,反射机制允许程序在执行期借助于 Reflection API 取得任何类的 ...
- Java反射机制Reflection
Java反射机制 1 .class文件 2 Class类 3 Class类与反射机制 4 Java反射机制的类库支持及简介 5 反射机制的定义与应用 6 反射机制Demo Java反射机制demo(一 ...
- java反射机制--reflection
反射,reflection,听其名就像照镜子一样,可以看见自己也可以看见别人的每一部分.在java语言中这是一个很重要的特性.下面是来自sun公司官网关于反射的介绍: Reflection is ...
- Java反射机制专题
·Java Reflection Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方 ...
- java反射机制深入详解
java反射机制深入详解 转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...
- 反射——Java反射机制
反射概述 什么是反射? ① 反射的概念是由Smith在1982年首次提出的,主要指程序可以访问.检测和修改它本身状态或行为的一种能力. ② JAVA反射机制是在运行状态中,对应任意一个类,都能 ...
- Java反射机制详解
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反 ...
- Java反射机制的学习
Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调 ...
- Java反射机制深入研究
ava 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? ...
随机推荐
- 【BZOJ-2893】征服王 最大费用最大流(带下界最小流)
2893: 征服王 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 156 Solved: 48[Submit][Status][Discuss] D ...
- jquery插件-表单验证插件-提示信息中文化与定制提示信息
接上一篇 2)messages 提示:修改默认的提示信息最简单的方法是引入message_zh.js文件即可! 如果需要在validate()方法内提示则可以使用本选项 类型:Object 说明:自定 ...
- JSR303注解
Annotation 属于Bean Validation 规范 应用位置 作用 对Hibernate Core中的元数据的影响 @AssertFalse yes field/property 检查被标 ...
- espcms /public/class_connector.php intval truncation Vul Arbitrary User Login
catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 Relevant Link:2. 漏洞触发条件3. 漏洞影响范围4. 漏 ...
- yocto系统介绍
The Yocto Project is an open source collaboration project that provides templates, tools and methods ...
- iOS 关于本地持久化存储的探讨
目前,用以本地化存储的方式有很多,常用的有以下: 1.临时缓存 先说说临时缓存,临时缓存一般相当于用来管理应用程序中全局需要常用的一些内容.比如当前用户的ID或者当前的定位信息等. 常用的方式就是写一 ...
- POJ 2484 A Funny Game(博弈论)
题目链接: 传送门 A Funny Game Time Limit: 1000MS Memory Limit: 10000K Description Alice and Bob decide ...
- Java多线程问题总结
前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...
- 创建与合并分支-git入门教程
在版本回退里,你已经知道,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支.HEAD严格来说不是指向提交,而 ...
- Deep Learning in NLP (一)词向量和语言模型
原文转载:http://licstar.net/archives/328 Deep Learning 算法已经在图像和音频领域取得了惊人的成果,但是在 NLP 领域中尚未见到如此激动人心的结果.关于这 ...