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 ...
随机推荐
- JS判斷文件大小
function findSize(file) { var dom = document.getElementById("file"); var fileSize = dom.fi ...
- JVM菜鸟进阶高手之路十(基础知识开场白)
转载请注明原创出处,谢谢! 最近没有什么实战,准备把JVM知识梳理一遍,先以开发人员的交流来谈谈jvm这块的知识以及重要性,依稀记得2.3年前用solr的时候老是经常oom,提到oom大家应该都不陌生 ...
- [LeetCode] 415 Add Strings && 67 Add Binary && 43 Multiply Strings
这些题目是高精度加法和高精度乘法相关的,复习了一下就做了,没想到难住自己的是C++里面string的用法. 原题地址: 415 Add Strings:https://leetcode.com/pro ...
- python django 使用 haystack:全文检索的框架
haystack:全文检索的框架whoosh:纯Python编写的全文搜索引擎jieba:一款免费的中文分词包 首先安装这三个包 pip install django-haystackpip inst ...
- 在JavaScript中使用json.js:访问JSON编码的某个值
演示: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3. ...
- 【重点突破】——Canvas技术绘制随机改变的验证码
一.引言 本文主要是我在学习Canvas技术绘图时的一个小练习,绘制随机改变的验证码图片,虽然真正的项目里不这么做,但这个练习是一个掌握Canvas技术很好的综合练习.(真正的项目中验证码图片使用服务 ...
- 支持向量机SVM(二)
[转载请注明出处]http://www.cnblogs.com/jerrylead 6 拉格朗日对偶(Lagrange duality) 先抛开上面的二次规划问题,先来看看存在等式约束的极值问题求法, ...
- Ubuntu 16安装GPU版本tensorflow
pre { direction: ltr; color: rgb(0, 0, 0) } pre.western { font-family: "Liberation Mono", ...
- Android02-控件
在android studio中,新建一个module时布局文件中就会默认带一个TextView,里面显示着一句话:Hello World ! 布局中通常放置的是android控件,下面介绍几个an ...
- 关于Struts与Ajax整合时的异常处理
关于Struts与Ajax整合时的异常处理问题: 问题还原: 从而当有异常发出时,会将异常信息发送到页面上.如下图所示:这是一个比较经典的过程: 错误提示页面: 由于sendError()方法里 ...