一、什么是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. 关于Android WebView上传文件的解决方案

    我们在开发需求的时候,难免会接入一下第三方的H5页面,有些H5页面是具有上传照片的功能,Android 中的 WebView是不能直接打开文件选择弹框的 接下来我讲简单提供一下解决方案,先说一下思路 ...

  2. scoke摘要

      登录|注册     关闭 永不磨灭的意志 /* ----------------500G的电影拷到了U盘上,U盘的重量会不会增加?----------------------*/       目录 ...

  3. js添加下拉列表的模糊搜寻

    1引入插件<script type="text/javascript"src="common/lib/jQueryComboSelect/jquery.combo. ...

  4. jquery对象和js对象

    <ul id="ul1">   <li id="li_1">01</li>   <li>02</li> ...

  5. IS 和AS

    http://www.cnblogs.com/haiyang1985/archive/2009/03/12/1410023.html 1一. as 运算符用于在兼容的引用类型之间执行某些类型的转换. ...

  6. java复习要点(一)------- java语言的特点、java的工作原理、配置环境变量、java命令的使用

    一.java语言的特点: (1)简单并面向对象 (2)鲁棒并安全: java语言在编译及运行程序时,都要进行严格的检查,防止不匹配问题的发生.如果引用一个非法类型,或执行一个非法类型操作,java减肥 ...

  7. css 浮动和清除浮动

    在写页面布局的过程中,浮动是大家经常用的属性.在好多的排版布局中都是用的的浮动比如说下面这些地方都是应用到了浮动. 在我学习浮动的时候可是熬坏了脑筋,在这里我分享一下我对浮动这块知识的总结. 一.浮动 ...

  8. Day1 Python基础学习

    一.编程语言分类 1.简介 机器语言:站在计算机的角度,说计算机能听懂的语言,那就是直接用二进制编程,直接操作硬件 汇编语言:站在计算机的角度,简写的英文标识符取代二进制去编写程序,本质仍然是直接操作 ...

  9. JS类继承常用方式发展史

    JS类继承常用方式发展史 涉及知识点 构造函数方式继承 1-继承单个对象 1.1 多步走初始版 1.2 多步走优化版 1.3 Object.create()方式 2-继承多个对象 2.1 遍历 Obj ...

  10. IDL 数组相关函数

    1.信息获取 Size()函数能够获取数组的相关信息.不设置关键字是,函数返回变量的基本信息:第一个返回值是变量的维数N_dims,但当变量是敞亮或未定义是返回值为0:第二个 到第N_dims+1个返 ...