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)的更多相关文章

  1. Java - 反射机制(Reflection)

    Java - 反射机制(Reflection)     > Reflection 是被视为 动态语言的关键,反射机制允许程序在执行期借助于 Reflection API 取得任何类的       ...

  2. Java反射机制Reflection

    Java反射机制 1 .class文件 2 Class类 3 Class类与反射机制 4 Java反射机制的类库支持及简介 5 反射机制的定义与应用 6 反射机制Demo Java反射机制demo(一 ...

  3. java反射机制--reflection

    反射,reflection,听其名就像照镜子一样,可以看见自己也可以看见别人的每一部分.在java语言中这是一个很重要的特性.下面是来自sun公司官网关于反射的介绍:    Reflection is ...

  4. Java反射机制专题

    ·Java Reflection Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方 ...

  5. java反射机制深入详解

    java反射机制深入详解  转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...

  6. 反射——Java反射机制

    反射概述 什么是反射? ①   反射的概念是由Smith在1982年首次提出的,主要指程序可以访问.检测和修改它本身状态或行为的一种能力. ②   JAVA反射机制是在运行状态中,对应任意一个类,都能 ...

  7. Java反射机制详解

    Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反 ...

  8. Java反射机制的学习

    Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调 ...

  9. Java反射机制深入研究

    ava 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”.   在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? ...

随机推荐

  1. Leetcode 300 Longest Increasing Subsequence

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

  2. Linux Running State Process ".so"、"code" Injection Technology

    catalog . 引言 . 基于so文件劫持进行代码注入 . 基于函数符号表(PLT)中库函数入口地址的修改进行代码注入 . PLT redirection through shared objec ...

  3. Android知识体系图

    网上看到,不知哪位大神总结的,存个档(需要放大网页才能看清)

  4. 最小生成树问题---Prim算法与Kruskal算法实现(MATLAB语言实现)

    2015-12-17晚,复习,甚是无聊,阅<复杂网络算法与应用>一书,得知最小生成树问题(Minimum spanning tree)问题.记之. 何为树:连通且不含圈的图称为树. 图T= ...

  5. Android中的Binder机制的简要理解

    转载自:http://www.linuxidc.com/Linux/2012-07/66195.htm http://blog.csdn.net/sunxingzhesunjinbiao/articl ...

  6. UVA1210Sum of Consecutive Prime Numbers(素数打表 + 连续和)

    题目链接 题意:输入一个数n (2 <= n <= 10000) 有多少种方案可以把n写成若干个连续素数之和 打出10000之内的素数表,然后再打出每个可能得到的和的方案数的表 #incl ...

  7. Facebook Messenger的后台架构是什么样的?

    后台的架构是由前台的需求决定的.做 mobile app 的需求跟做 web app 是不一样的,比如 mobile app 对实时性的要求比较强(移动用户都没耐性),移动设备网络不稳定(要能做到断点 ...

  8. phpcms响应式布局导航条

  9. Jquery 学习之基础一

    1.添加一个CSS类 $("button").click(function(){  $("#div1").addClass("important bl ...

  10. php-fpm服务挂掉

    今天发了个链接,可能同时在线的人瞬间比较多,结果网站报503错误,回去打开php-fpm错误日志一看,php-fpm服务挂掉了,报如下错误: [04-Apr-2016 15:38:04] NOTICE ...