一、什么是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. [js高手之路]Node.js+jade+mongoose实战todolist(分页,ajax编辑,删除)

    该系列文章索引: [js高手之路]node js系列课程-创建简易web服务器与文件读写 [js高手之路]node js系列课程-图解express+supervisor+ejs用法 [js高手之路] ...

  2. STM32获取DHT11温度传感器数据

    准备物件 STM32F103C8T6核心板 ST-LINK V2 DHT11 杜邦线若干 连接线 STM32F103C8T6芯片管脚图 管脚说明 连接仿真器 STM32 ST-LINKV2 VCC V ...

  3. 程序员的自我修养九Windows下的动态链接

    9.1 DLL简介 DLL即动态链接库的缩写,它相对于Linux下的共享对象. Windows下的DLL文件和EXE文件实际上是一个概念,它们都是有PE格式的二进制文件. 微软希望通过DLL机制加强软 ...

  4. iOS Storyboard约束详解

    链接:http://www.jianshu.com/p/b88c65ffc3eb 约束,就是指--此处略去1万字--都懂的,就不说了.直接进入实战环节. 本文的控件约束都是围绕着UITableView ...

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

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

  6. linux学习笔记:1.基础知识和命令行基本操作

    初次学习linux系统,想在这里记录自己的学习痕迹,如发现有不足之处,希望能指出,谢谢啦,之后的学习是在虚拟机VMware 10下的Red Hat Enterprise linux 6 的操作. 一. ...

  7. Mysql 协议嗅探

    需求 监听通过网卡的所有mysql流量,进行解析,可在不影响现有业务情况下,进行入侵检测(IDS)或数据集成 协议要点 起初发现 用mysql-front访问数据库和mysql 的客户端访问时数据包格 ...

  8. 关于ios11 tableView和ScrollView受导航栏影响向下偏移的问题

    看到网上说法ios11中automaticallyAdjustsScrollViewInsets属性被废弃,所以要设置tableView.contentInsetAdjustmentBehavior ...

  9. WordPress-基础设置之阅读设置

    对于第一次使用Wordpress系统的朋友,请先别着急发布文章及进行其他操作,为了更加科学的使用及管理wordpress,应该需要对其进行相关设置,主要涉及3个部分,一.常规设置,二.阅读设置,三.固 ...

  10. Sublime 3 打造成 Python/Django IDE开发利器

    Sublime Text 是一款非常强大的文本编辑器, 下面我们介绍如何将 Sublime Text 3 打造成一款 Python/Django 开发利器:   1. 安装 Sublime Text ...