Java反射机制能够获取的信息,与应用

一、什么是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 }

转载于:https://www.cnblogs.com/zyypro/p/7784032.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值