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 }
Java反射机制能够获取的信息,与应用的更多相关文章
- 浅谈Java反射机制 之 获取类的字节码文件 Class.forName("全路径名") 、getClass()、class
另一个篇:获取 类 的 方法 和 属性(包括构造函数) 先贴上Java反射机制的概念: AVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它 ...
- Java反射机制二 获取方法的返回值或参数的泛型信息
在使用反射机制时,我们经常需要知道方法的参数和返回值类型,很简单 ,下面上示例,示例中的两个方法非常相似 package deadLockThread; import java.lang.refle ...
- JAVA反射机制_获取字节码文件对象
是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称为java语 ...
- 通过java反射机制,获取对象的属性和值(包括所有继承的父类)
java的反射机制提供了两种方法: getDeclaredFields() :该方法能获取到本类的所有属性,包括private,protected和public,但不能获取到继承的父类的属性. get ...
- JAVA反射机制教程-获取类对象
1. 什么是类对象 类对象,就是用于描述这种类,都有什么属性,什么方法的 2. 获取类对象 获取类对象有3种方式(1). Class.forName(2). Hero.class(3). new He ...
- java反射子之获取方法信息(二)
一.获取方法 1.方法作用. 2. 二.获取方法信息.(修饰符,返回值,方法名称,参数列表,抛出的异常). ############################################## ...
- 浅谈Java反射机制 之 获取类的 方法 和 属性(包括构造函数)
上一篇 获取 类 的字节码文件 我们讲到了获取类的字节码文件的三种方法 第三种方法通过getClass("全路径名")获取字节码文件最符合要求 1.获取构造方法 先贴上我们要获取的 ...
- Java反射机制 之 获取类的 方法 和 属性(包括构造函数)(Day_06)
把自己立成帆,才能招来凤. 运行环境 JDK8 + IntelliJ IDEA 2018.3 本文中使用的jar包链接 https://files.cnblogs.com/files/papercy ...
- java反射机制 struts2 获取 action、method、invocation、proxy
ActionInvocation invocation = ActionContext.getContext().getActionInvocation(); Object action = invo ...
随机推荐
- C++中const几中用法
转载自:http://www.cnblogs.com/lichkingct/archive/2009/04/21/1440848.html 1. const修饰普通变量和指针 const修饰变量,一般 ...
- 三、js的函数
三.函数 函数是定义一次但却可以调用或执行任意多次的一段JS代码.函数有时会有参数,即函数被调用时指定了值的局部变量.函数常常使用这些参数来计算一个返回值,这个值也成为函数调用表达式的值. 1.函数声 ...
- pdf去水印
问: 我用Adobe acrobat professional 7.0 版想去掉添加的水印,不知道如何删除,请各位大 侠指点! 答:1.(功能表)工具→高级编辑工具→TouchUp对象工具 2.用滑鼠 ...
- java集合系列——Map介绍(七)
一.Map概述 0.前言 首先介绍Map集合,因为Set的实现类都是基于Map来实现的(如,HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的). 1:介绍 将键映射到 ...
- Robberies hdu 2955 01背包
Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- Finding LCM (最小公倍数)
Finding LCM Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu [Submit] ...
- 21.Linux-写USB键盘驱动(详解)
本节目的: 根据上节写的USB鼠标驱动,来依葫芦画瓢写出键盘驱动 1.首先我们通过上节的代码中修改,来打印下键盘驱动的数据到底是怎样的 先来回忆下,我们之前写的鼠标驱动的id_table是这样: 所以 ...
- NOIP2014_day2:无线网络发射器选址
#include<stdio.h>//NOIP2014 day2 :无线网络发射器选址 ,max=; ][]; void wifi(int a,int b,int c) { int i,j ...
- Weave Scope 容器地图 - 每天5分钟玩转 Docker 容器技术(80)
Weave Scope 的最大特点是会自动生成一张 Docker 容器地图,让我们能够直观地理解.监控和控制容器.千言万语不及一张图,先感受一下. 下面开始实践 Weave Scope. 安装 执行如 ...
- Excel导出插件
前言 一个游戏通常需要10多个Excel表格或者更多来配置,一般会通过导出csv格式读取配置. 本文提供导出Excel直接生成c#文件,对应数据直接生成结构体和数组,方便开发排错和简化重复写每个表格的 ...