1、概述
  a、通过Java反射机制,可以在程序中访问已经装载到JVM中的Java对象的描述、实现访问、检测和修改描述Java对象本身信息的功能。Java反射机制的功能非常强大,在java.lang.reflect包中提供了对该功能的支持。
  b、注意:在通过getFields()和getMethods()方法依次获得权限为public的成员变量和方法时,将包含从超类中继承到的成员变量和方法;而通过方法getDeclaredFiedls()和getDeclareMethods()只是获得在本类中定义的所有成员变量和方法。
  c、通过反射可访问的主要描述信息:

组成部分 访问方法 返回值类型 说明
包路径 getPackage() Package对象 获得该类的存放路径
类名称 getName() String对象 获得该类的名称
继承类 getSuperclass() Class对象 获得该类继承的类
实现接口 getInterfaces() Class型数组 获得该类实现的所有接口
构造方法 getConstructor() Constructor型数组 获得所有权限为public的构造方法
getConstructor(Class<?>...parameterTypes) Constructor对象 获得权限为public的指定构造方法
getDeclaredConstructors() Constructor型数组 获得所有构造方法,按声明顺序返回
getDeclaredConstructor(Class<?>...parameterTypes) Constructor对象 获得指定构造方法
方法 getMethods() Method型数组 获得所有权限为public的方法
getMethod(String name, Class<?>...parameterTypes) Method对象 获得权限为public的方法
getDeclaredMethods() Method型数组 获得所有方法,按声明顺序返回
getDeclaredMethods(String name, Class<?>...parameterTypes) Method对象 获得指定方法
成员变量 getFields() Field型数组 获得所有权限为public的成员变量
getField(String name) Field对象 获得权限为public的指定成员变量
getDeclaredFields() Field型数组 获得所有成员变量,按声明顺序返回
getDeclaredFields(String name) Field对象 获得指定成员变量
内部类 getClasses() Class型数组 获得所有权限为public的内部类
getDeclaredClasses() Class型数组 获得所有内部类
内部类的声明类 getDeclaringClass() Class对象 如果该类为内部类,则返回它的成员类,否则返回null

2、访问构造方法
  a、通过下列一组方法访问构造方法时,将返回Constructor类型的对象或数组。每个Constructor对象代表一个构造方法,利用Constructor对象可以操纵相应的构造方法。
    getConstructors()
    getConstructor(Class<?>...parameterTypes)
    getDeclaredConstructors()
    getDeclaredConstructor(Class<?>...parameterTypes)
  b、如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。例如访问一个入口参数类型依次为String和int型的构造方法,通过下面两种方法均可实现。
    objectClass.getDeclaredConstructor(String.class, int.class);
    objectClass.getDeclaredConstructor(new Class[]{String.class, int.class});
  c、Constructor类中提供的常用方法如下:

方  法 说  明
isVarArgs() 查看该构造方法是否允许带有可变数量的参数如果允许则返回true,否则返回false
getParameterTypes() 按照声明顺序以Class数组的形式获得该构造方法的各个参数的类型
getExceptionTypes() 以Class数组的形式获得该构造方法可能抛出的异常类型
newInstance(Object...initargs) 通过该构造方法利用指定参数创建一个该类的对象,如果未设置参数则表示采用默认无参数的构造方法
setAccessible(boolean flag) 如果该构造方法的权限为private,默认为不允许通过反射利用newInstance(Object...initargs)方法创建对象。如果先执行该方法并将入口参数设置为true,则允许创建
getModifiers() 获得可以解析出该构造方法所采用修饰符的整数

  d、通过java.lang.reflect.Modifier类可以解析出getModifiers()方法的返回值所表示的修饰符信息,在该类中提供了一系列用来解析的静态方法,即可以查看是否被指定的修饰符修饰,还可以以字符创的形式获得所有修饰符。
  e、Modifer类中的常用解析方法如下:

静态方法 说    明
isPublic(int mod) 查看是否被public修饰符修饰,如果是则返回true,否则返回false
isProtected(int mod) 查看是否被protected修饰符修饰,如果是则返回true,否则返回false
isPrivate(int mod) 查看是否被private修饰符修饰,如果是则返回true,否则返回false
isStatic(int mod) 查看是否被static修饰符修饰,如果是则返回true,否则返回false
isFinal(int mod) 查看是否被final修饰符修饰,如果是则返回true,否则返回false
toString(int od) 以字符创的形式返回所有修饰符

  f、例如:判断对象constructor所代表的构造方法是否被private修饰,以及以字符串形式获得该构造方法的所有修饰符的典型代码如下:
    int modifiers = constructor.getModifiers();
    boolean isEmbellishByPrivate = Modifier.isPrivate(modifiers);
    String embellishment = Modifier.toString(modifiers);

 1 package com.lzw;
 2
 3 public class Example_01 {
 4     String s;
 5     int i, i2, i3;
 6     private Example_01() {
 7     }
 8     protected Example_01(String s, int i) {
 9         this.s = s;
10         this.i = i;
11     }
12     public Example_01(String... strings) throws NumberFormatException {
13         if (0 < strings.length)
14             i = Integer.valueOf(strings[0]);
15         if (1 < strings.length)
16             i2 = Integer.valueOf(strings[1]);
17         if (2 < strings.length)
18             i3 = Integer.valueOf(strings[2]);
19     }
20     public void print() {
21         System.out.println("s=" + s);
22         System.out.println("i=" + i);
23         System.out.println("i2=" + i2);
24         System.out.println("i3=" + i3);
25     }
26 }

View Code

 1 package com.lzw;
 2
 3 import java.lang.reflect.*;
 4
 5 public class Main_01 {
 6
 7     public static void main(String[] args) {
 8
 9         Example_01 example = new Example_01("10", "20", "30");
10         Class<? extends Example_01> exampleC = example.getClass();
11
12         Constructor[] declaredConstructors = exampleC.getDeclaredConstructors();
13         for (int i = 0; i < declaredConstructors.length; i++) {
14             Constructor<?> constructor = declaredConstructors[i];
15             System.out.println("查看是否允许带有可变数量的参数:" + constructor.isVarArgs());
16             System.out.println("该构造方法的入口参数类型依次为:");
17             Class[] parameterTypes = constructor.getParameterTypes();
18             for (int j = 0; j < parameterTypes.length; j++) {
19                 System.out.println(" " + parameterTypes[j]);
20             }
21             System.out.println("该构造方法可能抛出的异常类型为:");
22             Class[] exceptionTypes = constructor.getExceptionTypes();
23             for (int j = 0; j < exceptionTypes.length; j++) {
24                 System.out.println(" " + exceptionTypes[j]);
25             }
26             Example_01 example2 = null;
27             while (example2 == null) {
28                 try {
29                     if (i == 2)
30                         example2 = (Example_01) constructor.newInstance();
31                     else if (i == 1)
32                         example2 = (Example_01) constructor.newInstance("7", 5);
33                     else {
34                         Object[] parameters = new Object[] { new String[] {
35                                 "100", "200", "300" } };
36                         example2 = (Example_01) constructor
37                                 .newInstance(parameters);
38                     }
39                 } catch (Exception e) {
40                     System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
41                     constructor.setAccessible(true);
42                 }
43             }
44             if(example2!=null){
45             example2.print();
46             System.out.println();
47             }
48         }
49
50     }
51
52 }

View Code

3、访问成员变量
  a、在通过下列一组方法访问成员变量时,将返回Field类型的对象或数组。每个Field对象代表一个成员变量,利用Field对象可以操纵相应的成员变量。
    getFields()
    getField(String name)
    getDeclaredFields()
    getDeclaredField(String name)
  b、如果是访问指定的成员变量,可以通过该成员变量的名称来访问。例如,访问一个名称为birthday的成员变量,访问方法如下:
    object.getDeclaredField("birthday");
  c、Field类的常用方法:

方法 说  明
getName() 获得该成员变量的名称
getType() 获得表示该成员变量类型的Class对象
get(Object obj) 获得指定对象obj中成员变量的值,返回值为Object型
set(Object obj, Object obj) 将指定对象obj中成员变量的值设置为value
getInt(Object obj) 获得指定对象obj中类型为int的成员变量的值
setInt(Object obj, int i) 将指定对象obj中类型为int的成员变量的值设置为i
getFloat(Object obj) 获得指定对象obj中类型为float的成员变量的值
setFloat(Object obj, float f) 将指定对象obj中类型为float的成员变量的值设置为f
getBoolean(Object obj) 获得指定对象obj中类型为boolean的成员变量的值
setBoolean(Object obj, boolean z) 获得指定对象obj中类型为boolean的成员变量的值设置为z
setAccessible(boolean flag) 此方法可以设置是否忽略权限限制直接访问private等私有权限的成员变量
getModifiers() 获得可以解析出该成员变量所采用修饰符的整数

1 public class Example_02 {
2     int i;
3     public float f;
4     protected boolean b;
5     private String s;
6 }

View Code

 1 import java.lang.reflect.*;
 2 public class Main_02 {
 3     public static void main(String[] args) {
 4         Example_02 example = new Example_02();
 5         Class exampleC = example.getClass();
 6         // 获得所有成员变量
 7         Field[] declaredFields = exampleC.getDeclaredFields();
 8         for (int i = 0; i < declaredFields.length; i++) {
 9             Field field = declaredFields[i]; // 遍历成员变量
10             // 获得成员变量名称
11             System.out.println("名称为:" + field.getName());
12             Class fieldType = field.getType(); // 获得成员变量类型
13             System.out.println("类型为:" + fieldType);
14             boolean isTurn = true;
15             while (isTurn) {
16                 // 如果该成员变量的访问权限为private,则抛出异常,即不允许访问
17                 try {
18                     isTurn = false;
19                     // 获得成员变量值
20                     System.out.println("修改前的值为:" + field.get(example));
21                     // 判断成员变量的类型是否为int型
22                     if (fieldType.equals(int.class)) {
23                         System.out.println("利用方法setInt()修改成员变量的值");
24                         field.setInt(example, 168); // 为int型成员变量赋值
25                         // 判断成员变量的类型是否为float型
26                     } else if (fieldType.equals(float.class)) {
27                         System.out.println("利用方法setFloat()修改成员变量的值");
28                         // 为float型成员变量赋值
29                         field.setFloat(example, 99.9F);
30                         // 判断成员变量的类型是否为boolean型
31                     } else if (fieldType.equals(boolean.class)) {
32                         System.out.println("利用方法setBoolean()修改成员变量的值");
33                         // 为boolean型成员变量赋值
34                         field.setBoolean(example, true);
35                     } else {
36                         System.out.println("利用方法set()修改成员变量的值");
37                         // 可以为各种类型的成员变量赋值
38                         field.set(example, "MWQ");
39                     }
40                     // 获得成员变量值
41                     System.out.println("修改后的值为:" + field.get(example));
42                 } catch (Exception e) {
43                     System.out.println("在设置成员变量值时抛出异常,"
44                             + "下面执行setAccessible()方法!");
45                     field.setAccessible(true); // 设置为允许访问
46                     isTurn = true;
47                 }
48             }
49             System.out.println();
50         }
51     }
52 }

View Code

4、访问方法
  a、在通过下列一组方法访问方法时,将返回Method类型的对象或数组。每个Method对象代表一个方法,利用Method对象可以操纵相应的方法。
    getMethods()
    getMethod(String name, Class<?>...parameterTypes)
    getDeclaredMethods()
    getDeclaredMethod(String name, Class<?>...parameterTypes)
  b、如果是访问指定的方法,需要根据该方法的名称和入口参数的类型来访问。例如,访问一个名称为print、入口参数类型依次为String和int型的方法,通过下面两种方式均可实现:
    objectClass.getDeclaredMethod("print", String.class, int.class)
    objectClass.getDeclaredMethod("print", new Class[]{String.class, int.class})
  c、在反射中执行具有可变数量的参数的构造方法时,需要将入口参数定义成二维数组。
  d、Method类中提供的常用方法如下:

方法 说  明
getName() 获得该方法的名称
getParameterTypes() 按照声明顺序以Class数组的形式获得该方法的各个参数的类型
getReturnType() 以Class对象的形式获得该方法的返回值的类型
getExceptionTypes() 以Class数组的形式获得该方法可能跑出的异常类型
invoke(Object obj, Object...args) 利用指定参数args执行指定对象obj中的该方法,返回值为Object型
isVarArgs() 查看该构造方法是否允许带有可变数量的参数,如果允许则返回true,否则返回false
getModifiers() 获得可以解析出该方法所采用修饰符的整数

 1 package com.lzw;
 2
 3 public class Example_03 {
 4     static void staticMethod() {
 5         System.out.println("执行staticMethod()方法");
 6     }
 7
 8     public int publicMethod(int i) {
 9         System.out.println("执行publicMethod()方法");
10         return i * 100;
11     }
12
13     protected int protectedMethod(String s, int i)
14             throws NumberFormatException {
15         System.out.println("执行protectedMethod()方法");
16         return Integer.valueOf(s) + i;
17     }
18
19     private String privateMethod(String... strings) {
20         System.out.println("执行privateMethod()方法");
21         StringBuffer stringBuffer = new StringBuffer();
22         for (int i = 0; i < strings.length; i++) {
23             stringBuffer.append(strings[i]);
24         }
25         return stringBuffer.toString();
26     }
27 }

View Code

 1 package com.lzw;
 2
 3 import java.lang.reflect.*;
 4
 5 public class Main_03 {
 6     public static void main(String[] args) {
 7         Example_03 example = new Example_03();
 8         Class exampleC = example.getClass();
 9
10         // 获得所有方法
11         Method[] declaredMethods = exampleC.getDeclaredMethods();
12         for (int i = 0; i < declaredMethods.length; i++) {
13             Method method = declaredMethods[i]; // 遍历方法
14             System.out.println("名称为:" + method.getName()); // 获得方法名称
15             System.out.println("是否允许带有可变数量的参数:" + method.isVarArgs());
16             System.out.println("入口参数类型依次为:");
17             // 获得所有参数类型
18             Class[] parameterTypes = method.getParameterTypes();
19             for (int j = 0; j < parameterTypes.length; j++) {
20                 System.out.println(" " + parameterTypes[j]);
21             }
22             // 获得方法返回值类型
23             System.out.println("返回值类型为:" + method.getReturnType());
24             System.out.println("可能抛出的异常类型有:");
25             // 获得方法可能抛出的所有异常类型
26             Class[] exceptionTypes = method.getExceptionTypes();
27             for (int j = 0; j < exceptionTypes.length; j++) {
28                 System.out.println(" " + exceptionTypes[j]);
29             }
30             boolean isTurn = true;
31             while (isTurn) {
32                 // 如果该方法的访问权限为private,则抛出异常,即不允许访问
33                 try {
34                     isTurn = false;
35                     if("staticMethod".equals(method.getName()))
36                         method.invoke(example); // 执行没有入口参数的方法
37                     else if("publicMethod".equals(method.getName()))
38                         System.out.println("返回值为:"
39                                 + method.invoke(example, 168)); // 执行方法
40                     else if("protectedMethod".equals(method.getName()))
41                         System.out.println("返回值为:"
42                                 + method.invoke(example, "7", 5)); // 执行方法
43                     else if("privateMethod".equals(method.getName())) {
44                         Object[] parameters = new Object[] { new String[] {
45                                 "M", "W", "Q" } }; // 定义二维数组
46                         System.out.println("返回值为:"
47                                 + method.invoke(example, parameters));
48                     }
49                 } catch (Exception e) {
50                     System.out.println("在执行方法时抛出异常,"
51                             + "下面执行setAccessible()方法!");
52                     method.setAccessible(true); // 设置为允许访问
53                     isTurn = true;
54                 }
55             }
56             System.out.println();
57         }
58     }
59 }

View Code

转载于:https://www.cnblogs.com/studycode/p/9540076.html

16.1 Class类与Java反射相关推荐

  1. java 反射 本类,关于Java反射中基本类型的class有关问题

    关于Java反射中基本类型的class问题 1. 基本类型的class和其对应包装类的class是不同的,所以在获得Method指定参数的时候,需要精确指定参数的类型,即 setInt(int x) ...

  2. java 防止反射_如何防止JAVA反射对单例类的攻击?

    在我的上篇随笔中,我们知道了创建单例类有以下几种方式: (1).饿汉式; (2).懒汉式(.加同步锁的懒汉式.加双重校验锁的懒汉式.防止指令重排优化的懒汉式); (3).登记式单例模式; (4).静态 ...

  3. Java反射面试总结(一)

    什么是反射? Java的反射是指在程序运行时,对于任意一个类,都可以获取到这个类的所有属性和方法,并能够对其进行操作.通过反射机制,可以在程序运行时动态地创建对象.调用方法.获取属性值等.反射可以帮助 ...

  4. Java反射探索研究

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankakay 摘要:本文详细深入讲解是Java中反射的机制,并介绍了如何通过反射来生成对象.调用函数.取得 ...

  5. Java反射(详述版)

    一.什么是反射? 我们先来看一个例子: package venus; public class Student {public String name;public Student(){System. ...

  6. JAVA反射机制及其原理实现

    9.1 概念 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:public.protected.private. OO ...

  7. 12000+字Java反射,一起全面了解Java反射机制,为学习框架铺路

    文章目录 Java反射机制 理解Class类 获取Class类实例 类的加载过程 类加载器ClassLoader 创建运行时类的对象 获取运行时类的结构 调用运行时类的指定结构 动态代理 Java反射 ...

  8. Java反射机制API

    实现 Java 反射机制的类都位于 java.lang.reflect 包中,java.lang.Class 类是 Java 反射机制 API 中的核心类. java.lang.Class 类 jav ...

  9. Java反射示例教程

    Java反射示例教程 Java Reflection提供检查和修改应用程序的运行时行为的能力.Java中的反射是核心java的一个先进主题.使用java反射我们可以检查一个类,在运行时接口,枚举,获取 ...

  10. 非常好的Java反射例子

    1.Java反射的概念 反射含义:可以获取正在运行的Java对象. 2.Java反射的功能 1)可以判断运行时对象所属的类 2)可以判断运行时对象所具有的成员变量和方法 3)通过反射甚至可以调用到pr ...

最新文章

  1. 辽宁交通高等专科学校计算机专业,辽宁省交通高等专科学校怎么样 全国排名第几...
  2. python资源百度云_Python Selenium 百度云分享链接资源 批量保存
  3. python保存创建文件报错 with open(fileName,‘w‘) as fp: IOError: [Errno 22] invalid mode (‘w‘) or filename
  4. Question: Database Of Tumor Suppressors And/Or Oncogenes
  5. 图像灰度化(C语言实现)
  6. 3D 机器视觉 02 - FPGA生成N位元格雷码
  7. IBM收购数据库安全公司 围剿Oracle之心不死
  8. android 微信webview,android实现用户体验超棒的微信WebView进度条
  9. opengl入门6。1
  10. 铺地毯(luogu 1003)
  11. 锐捷长ping_锐捷交换机命令
  12. 液晶面板里面有些什么配件_TFT液晶屏的基本组成和部件是什么
  13. 《有效的单元测试》第三章
  14. Number of Triplets
  15. QT:主页面全屏显示(根据显示屏分辨率调整主页面尺寸)
  16. 存储、冯诺伊曼和哈佛结构之间的关系
  17. android导入html文件怎么打开,Android浏览器如何打开本地html文件
  18. java故事之致敬坚持梦想的人
  19. 若依系统用户权限模型分析
  20. 从移动到桌面—ARM挑战X86

热门文章

  1. 安装红帽linux显示半屏,在linux下模拟win+arrow来左右半屏当前窗口
  2. java线程的状态改变(练习)
  3. eclipse、EditPlus等编辑器选中列(块)的方法
  4. C++,next_permutation(start_array_index,end_index)的使用
  5. 阶段3 2.Spring_10.Spring中事务控制_2 作业-基于注解的AOP实现事务控制及问题分析_上...
  6. PCRE demo【转】
  7. tomcat 7服务器跨域问题解决
  8. css3实现进度条的模拟
  9. HDOJ-2095 Find your present (2) / NYOJ-528 找球号(三)
  10. httpHandler实现.Net无后缀名Web访问