一、什么是Java反射机制?

【1】反射机制是在运行状态中,对于任何一个类,都能够知道这个类的所有属性和方法;

【2】对于任意一个对象,都能够调用它的任意一个属性和方法;

像这种动态获取类的信息以及动态调用对象的方法的骚操作称为java语言的反射机制。


二、Java反射机制能够获取及操作哪些信息?

【1】获取类的包名 + 类名

 1 package com.zyy.test.reflect;
2
3 public class TestReflect {
4
5 public static void main(String[] args) throws ClassNotFoundException {
6 Class<?> class1 = TestReflect.class;
7 Class<?> class2 = new TestReflect().getClass();
8 Class<?> class3 = Class.forName("com.zyy.test.reflect.TestReflect");
9
10 System.out.println("包名+类名:" + class1.getName());
11 System.out.println("类名" + class1.getSimpleName());
12 System.out.println("包名+类名:" + class2.getName());
13 System.out.println("类名" + class2.getSimpleName());
14 System.out.println("包名+类名:" + class3.getName());
15 System.out.println("类名" + class3.getSimpleName());
16
17 /*
18 打印结果如下:
19 包名+类名:com.zyy.test.reflect.TestReflect
20 类名TestReflect
21 包名+类名:com.zyy.test.reflect.TestReflect
22 类名TestReflect
23 包名+类名:com.zyy.test.reflect.TestReflect
24 类名TestReflect
25 */
26 }
27
28 }

 【2】获取某个类的父类与实现的接口信息

 1 package com.zyy.test.reflect;
2
3 import java.io.Serializable;
4
5 public class TestReflect implements Serializable{
6
7 private static final long serialVersionUID = -8047590384784013451L;
8
9 public static void main(String[] args) throws ClassNotFoundException {
10 Class<?> clazz = Class.forName("com.zyy.test.reflect.TestReflect");
11 //获取父类信息
12 System.out.println("父类:" + clazz.getSuperclass().getName());
13 //获取实现的所有接口信息
14 Class<?>[] interfaces = clazz.getInterfaces();
15 for (int i = 0; i < interfaces.length; i++) {
16 System.out.println("接口:" + interfaces[i].getName());
17 }
18
19 /*打印结果如下:
20 父类:java.lang.Object
21 接口:java.io.Serializable
22 */
23 }
24
25 }

【3】获取某个类的构造信息以及使用构造进行赋值

 1 package com.zyy.test.reflect;
2
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.InvocationTargetException;
5 import java.math.BigDecimal;
7
8 public class TestReflect {
9
10 public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
11 IllegalArgumentException, InvocationTargetException {
12
13 Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");
14 Constructor<?>[] constructors = clazz.getConstructors();
15
16 for (int i = 0; i < constructors.length; i++) {
17 System.out.println("构造" + i + constructors[i].getName() + "的参数为:");
18 //获取构造的参数信息
19 Class<?>[] types = constructors[i].getParameterTypes();
20 for (int j = 0; j < types.length; j++) {
21 System.out.println(types[j].getName() + " ");
22 }
23 }
24
25 /*打印结果:
26 构造0com.zyy.test.reflect.BookFacaed的参数为:
27 java.lang.String
28 java.math.BigDecimal
29 构造1com.zyy.test.reflect.BookFacaed的参数为:
30 java.lang.String
31 构造2com.zyy.test.reflect.BookFacaed的参数为:
32 */
33
34 //实例化拥有2个参数的构造方法
35 BookFacaed bookFacaed = (BookFacaed)constructors[0].newInstance("《数据结构》", new BigDecimal(100));
36 System.out.println(bookFacaed); //调用实体的toString方法打印
37
38 //通过反射机制直接实例化对象
39 BookFacaed bookFacaed2 = (BookFacaed)clazz.newInstance();
40 bookFacaed2.setName("《数据结构》");
41 bookFacaed2.setPrice(new BigDecimal(100));
42 System.out.println(bookFacaed2);
43 }
44
45 }
46
47 class BookFacaed {
48 private String name;
49
50 private BigDecimal price;
51
52 public BookFacaed () {}
53
54 public BookFacaed (String name) {
55 this.name = name;
56 }
57
58 public BookFacaed (String name, BigDecimal price) {
59 this.name = name;
60 this.price = price;
61 }
62
63 public String getName() {
64 return name;
65 }
66
67 public void setName(String name) {
68 this.name = name;
69 }
70
71 public BigDecimal getPrice() {
72 return price;
73 }
74
75 public void setPrice(BigDecimal price) {
76 this.price = price;
77 }
78
79 @Override
80 public String toString() {
81 return name + "的价格为:" + price;
82 }
83 }

【4】获取某个类的所有属性信息

 1 package com.zyy.test.reflect;
2
3 import java.lang.reflect.Field;
4 import java.lang.reflect.Modifier;public class TestReflect {
5
6 public static void main(String[] args) throws ClassNotFoundException {
7 Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");
8 Field[] fields = clazz.getDeclaredFields();
9 for (int i = 0; i < fields.length; i++) {
10 //获得类属性的修饰符
11 String pri = Modifier.toString(fields[i].getModifiers());
12 //获得类属性的类型
13 Class<?> type = fields[i].getType();
14
15 System.out.println(pri + " " + type.getSimpleName() + " " + fields[i].getName());
16 /*打印结果:
17 private String name
18 private BigDecimal price
19 */
20 }
21
22 /*如果要获取类的接口或者父类的属性使用下面的方法获取*/
23 Field[] fields2 = clazz.getFields();
24 }
25
26 }

【5】获取某个类的所有方法及其属性信息

 1 package com.zyy.test.reflect;
2
3 import java.lang.reflect.Method;
4 import java.lang.reflect.Modifier;
5 import java.math.BigDecimal;
6
7
8 public class TestReflect {
9
10 public static void main(String[] args) throws ClassNotFoundException {
11 Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");
12
13 Method[] methods = clazz.getMethods();
14 for (int i = 0; i < methods.length; i++) {
15 System.out.println("方法" + (i + 1));
16 //获取方法的修饰符
17 String pri = Modifier.toString(methods[i].getModifiers());
18 //获取方法的返回类型
19 Class<?> type = methods[i].getReturnType();
20 //获取方法的持有参数
21 Class<?>[] params = methods[i].getParameterTypes();
22 for (int j = 0; j < params.length; j++) {
23 System.out.println(params[j].getName());
24 }
25 //获取方法的抛出异常
26 Class<?>[] excTypes = methods[i].getExceptionTypes();
27 for (int j = 0; j < excTypes.length; j++) {
28 System.out.println(excTypes[j].getName());
29 }
30 }
31 }
32
33 }

【6】反射机制调用某个类的某个方法

 1 package com.zyy.test.reflect;
2
3 import java.lang.reflect.InvocationTargetException;
4 import java.lang.reflect.Method;
5 import java.math.BigDecimal;
6
7 public class TestReflect {
8
9 public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException,
10 IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
11
12 Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");
13 //调用BookFacaed的addBook()方法
14 Method method = clazz.getMethod("addBook", String.class);
15 method.invoke(clazz.newInstance(), "《数据结构》");
16 }
17
18 }
19
20 class BookFacaed {
21 private String name;
22
23 private BigDecimal price;
24
25 public BookFacaed () {}
26
27 public BookFacaed (String name) {
28 this.name = name;
29 }
30
31 public BookFacaed (String name, BigDecimal price) {
32 this.name = name;
33 this.price = price;
34 }
35
36 public void addBook(String name) {
37 System.out.println("添加书:" + name);
38 }
39
40 public String getName() {
41 return name;
42 }
43
44 public void setName(String name) {
45 this.name = name;
46 }
47
48 public BigDecimal getPrice() {
49 return price;
50 }
51
52 public void setPrice(BigDecimal price) {
53 this.price = price;
54 }
55
56 @Override
57 public String toString() {
58 return name + "的价格为:" + price;
59 }
60 }

【7】通过反射机制操作某个类的属性

 1 package com.zyy.test.reflect;
2
3 import java.lang.reflect.Field;
4 import java.math.BigDecimal;
5
6 public class TestReflect {
7
8 public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException,
9 SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
10
11 Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");
12 Object obj = clazz.newInstance();
13 //调用BookFacaed的name属性,并赋值
14 Field field = clazz.getDeclaredField("name");
15 field.setAccessible(true); //操作属性修饰符为private则必须用此申明
16 field.set(obj, "《数据结构》");
17
18 System.out.println(field.get(obj));
19 }
20
21 }

三、Java反射机制能够帮助我们做什么?

【1】打破泛型的约束

 1 package com.zyy.test.reflect;
2
3 import java.lang.reflect.InvocationTargetException;
4 import java.lang.reflect.Method;
5 import java.math.BigDecimal;
6 import java.util.ArrayList;
7 import java.util.List;
8
9 public class TestReflect {
10
11 public static void main(String[] args) throws NoSuchMethodException, SecurityException,
12 IllegalAccessException, IllegalArgumentException, InvocationTargetException {
13
14 List<Integer> list = new ArrayList<Integer>();
15 //设定了以上泛型之后,list集合中是无法插入String或者其他类型的数据的
16 //通过泛型我们便可打破这个约束,代码如下
17 Method method = list.getClass().getMethod("add", Object.class);
18 method.invoke(list, "看插入了一个String数据");
19
20 System.out.println(list.get(0));
21 }
22
23 }

【2】反射机制实现动态代理

  Spring的一个核心设计思想便是AOP(面向切面编程),那么AOP是通过动态代理实现的,而动态代理则用到了反射机制;

  用了反射机制的好处在于,一个代理就能处理所有的委托,而不用一个委托类就创建一个代理;

 1 package com.zyy.test.reflect;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5 import java.lang.reflect.Proxy;
6
7
8 public class TestReflect {
9
10 public static void main(String[] args) {
11 //创建代理类并绑定委托类
12 FruitProxy proxy = new FruitProxy();
13 Fruit fruit = (Fruit) proxy.bind(new Apple());
14 fruit.eatFruit();
15 }
16
17 }
18
19 interface Fruit {
20 public void eatFruit();
21 }
22
23 //委托类
24 class Apple implements Fruit {
25 public void eatFruit() {
26 System.out.println("eat Apple");
27 }
28 }
29
30 //代理类
31 class FruitProxy implements InvocationHandler{
32 private Object obj;
33
34 //绑定对象
35 public Object bind(Object obj) {
36 this.obj = obj;
37 return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
38 }
39
40 @Override
41 public Object invoke(Object proxy, Method method, Object[] args)
42 throws Throwable {
43 System.out.println("这里添加执行内容,<aop:before/>标签熟悉吧,作用一样");
44 Method result = (Method) method.invoke(obj, args);
45 System.out.println("这里添加执行内容,<aop:after/>标签熟悉吧,作用一样");
46
47 return result;
48 }
49
50 }

【3】反射机制应用于工厂模式

对于普通的工厂,新增一个子类的时候,工厂就需要进行调整,而加入反射机制后,工厂则不需要关心你有多少个子类;

 1 package com.zyy.test.reflect;
2
3 public class TestReflect {
4
5 public static void main(String[] args) throws InstantiationException,
6 IllegalAccessException, ClassNotFoundException {
7
8 Fruit fruit = (Fruit) Factory.getInstance("com.zyy.test.reflect.Orange");
9 fruit.eatFruit();
10 }
11
12 }
13
14 interface Fruit {
15 public void eatFruit();
16 }
17
18 class Apple implements Fruit {
19 public void eatFruit() {
20 System.out.println("eat Apple");
21 }
22 }
23
24 class Orange implements Fruit {
25 public void eatFruit() {
26 System.out.println("eat Orange");
27 }
28 }
29
30 class Factory {
31 public static Object getInstance (String className) throws InstantiationException,
32 IllegalAccessException, ClassNotFoundException {
33
34 Object obj = Class.forName(className).newInstance();
35 return obj;
36 }
37
38 }

Java反射机制能够获取的信息,与应用的更多相关文章

  1. 浅谈Java反射机制 之 获取类的字节码文件 Class.forName("全路径名") 、getClass()、class

    另一个篇:获取 类 的 方法 和 属性(包括构造函数) 先贴上Java反射机制的概念: AVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它 ...

  2. Java反射机制二 获取方法的返回值或参数的泛型信息

    在使用反射机制时,我们经常需要知道方法的参数和返回值类型,很简单  ,下面上示例,示例中的两个方法非常相似 package deadLockThread; import java.lang.refle ...

  3. JAVA反射机制_获取字节码文件对象

    是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称为java语 ...

  4. 通过java反射机制,获取对象的属性和值(包括所有继承的父类)

    java的反射机制提供了两种方法: getDeclaredFields() :该方法能获取到本类的所有属性,包括private,protected和public,但不能获取到继承的父类的属性. get ...

  5. JAVA反射机制教程-获取类对象

    1. 什么是类对象 类对象,就是用于描述这种类,都有什么属性,什么方法的 2. 获取类对象 获取类对象有3种方式(1). Class.forName(2). Hero.class(3). new He ...

  6. java反射子之获取方法信息(二)

    一.获取方法 1.方法作用. 2. 二.获取方法信息.(修饰符,返回值,方法名称,参数列表,抛出的异常). ############################################## ...

  7. 浅谈Java反射机制 之 获取类的 方法 和 属性(包括构造函数)

    上一篇 获取 类 的字节码文件 我们讲到了获取类的字节码文件的三种方法 第三种方法通过getClass("全路径名")获取字节码文件最符合要求 1.获取构造方法 先贴上我们要获取的 ...

  8. Java反射机制 之 获取类的 方法 和 属性(包括构造函数)(Day_06)

    把自己立成帆,才能招来凤. 运行环境 JDK8 + IntelliJ IDEA 2018.3  本文中使用的jar包链接 https://files.cnblogs.com/files/papercy ...

  9. java反射机制 struts2 获取 action、method、invocation、proxy

    ActionInvocation invocation = ActionContext.getContext().getActionInvocation(); Object action = invo ...

随机推荐

  1. 【SQL】- 基础知识梳理(三) - SQL连接查询

    一.引言 有时为了得到一张报表的完整数据,需要从两个或更多的表中获取结果,这时就用到了"连接查询". 二.连接查询 连接查询的定义: 数据库中的表通过键将彼此联系起来,从而获取这些 ...

  2. KMP算法的来龙去脉

    1. 引言 字符串匹配是极为常见的一种模式匹配.简单地说,就是判断主串TT中是否出现该模式串PP,即PP为TT的子串.特别地,定义主串为T[0-n−1]T[0-n−1],模式串为P[0-p−1]P[0 ...

  3. Split分割字符串

    第一种方法:打开vs.net新建一个控制台项目.然后在Main()方法下输入下面的程序. string s="abcdeabcdeabcde"; string[] sArray=s ...

  4. Oculus关于Internal Error:OVR53225466报错解决方法

    安装Oculus过程中可能会出现Internal Error:OVR53225466报错提示,如附件所示: 解决方法:修改hosts文件 操作方法: (1)以管理员方式打开记事本: (2)打开C:\W ...

  5. Java虚拟中内存分块

    Java虚拟机JVM(Java Virtual Machine)中内存分块 JAVA中通常分为5个区域虚拟机栈.堆.方法区.程序计数器.本地方法区.我们一般讲的是Java虚拟机管理的四个区域虚拟机栈. ...

  6. GCD hdu2588

    GCD Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  7. DB2插入数据 sqlcode302 sqlstate22001错误如何解决?

    总结:出现这种错误的原因主要是,插入数据时的长度和数据库中定义的长度不匹配或超出限制.

  8. Python实战之Selenium自动化测试web刷新FW

    需求:将手工登录,手工刷新服务器的FW转化为Python+Selenium实现自动化操作. 1.创建用户表,实现数据与脚本分离.需要读取模块. 2.自动化刷新FW. 不说话,直接上代码: 1userd ...

  9. C# readonly

    当某个字段是引用类型,并且该字段被标记为readonly时,不可改变的是引用,而非字段引用的对象,例如:

  10. 分页查询不知你是否真正的懂和PHP的正则的应用和一些性能优化

    一.不废话太多  直接进入例子. 1  问题: 有一张收藏表,里面存储的是用户和图书ID.数据量为1亿.现在要求分页获取所有用户ID(不重复),写下你的sql语句.   表结构大致如下:       ...