1.目标与意义
反射是Java开发中一个非常重要的概念,掌握了反射的知识,才能更好的学习Java高级课程。如Spring框架的核心就是使用Java反射实现的,而且对做一些Java底层的操作会很有帮助。
强烈建议大家手动敲一遍,会收获颇丰!
目标:
- (1)、能够理解并应用反射机制。
- (2)、能够了解反射机制在集合泛型中的应用。
- (3)、有利于更好的学习框架等Java高级技术。
2.Class类的使用
(1) 在面向对象的世界里,万事万物皆对象。(java语言中,静态的成员、普通数据类型除外)
问题: 类是不是对象呢?类是(哪个类的对象呢?)谁的对象呢?
答: 类是对象,类是java.lang.Class类的实例对象(类对象)
(2)这个对象到底如何表示(三种表示方法)
- 通过隐藏的静态成员变量Student.class获取
- 通过对象 stu1.getClass();方法获取
- 通过Class.forName(类路径) 获取
1 | package com.rocklei123.reflect; |
另外Class类对象不可以new 出来,因为它的构造方法为私有的,只有JVM 才可以创建类对象
1 | /* |
3.Java动态加载类
请大家区分编译、运行: 编译时刻加载类是静态加载类、运行时刻加载类是动态加载类
(1) new 创建的对象,是静态类加载,在编译时刻就需要加载所有的可能使用到的类。
(2)Class.forName(“类的全称”)不仅表示了,类的类类型,还代表了动态加载类,在运行时刻加载。
4.图解类的正常加载过程和反射的原理在与class对象
图解类的正常加载过程和反射的原理在与class对象
图解类的加载过程中各对象创建时占用的JVM内存区域
5.基本的数据类型、void关键字的类类型
基本的数据类型、void等关键字等都存在类类型
1 | package com.rocklei123.reflect; |
6.通过反射获取方法信息、成员变量、构造函数信息
实体类信息:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38package com.rocklei123.spring.transaction.transferAccount.entity;
/**
* @Title: SpringTransactionTest
* @Description:
* @Author: rocklei123
* @Date: 2018/8/14 14:52
* @Version: 1.0
*/
public class User {
private String username;
private double money;
public User(String username, double money) {
this.username = username;
this.money = money;
}
public User(){
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
}
反射ClassUtil打印类的信息,包括类的成员函数、成员变量(只获取成员函数):
1 | package com.rocklei123.reflect; |
执行结果:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33类加载器为:sun.misc.Launcher$AppClassLoader@4921a90
包名为:package com.rocklei123.spring.transaction.transferAccount.entity
类名称为:com.rocklei123.spring.transaction.transferAccount.entity.User
===========================================
方法名称为:getUsername , 方法返回值类型为:java.lang.String 方法参数类型()
------------------------------------
方法名称为:setUsername , 方法返回值类型为:void 方法参数类型(java.lang.String)
------------------------------------
方法名称为:getMoney , 方法返回值类型为:double 方法参数类型()
------------------------------------
方法名称为:setMoney , 方法返回值类型为:void 方法参数类型(double)
------------------------------------
方法名称为:wait , 方法返回值类型为:void 方法参数类型(longint)
------------------------------------
方法名称为:wait , 方法返回值类型为:void 方法参数类型(long)
------------------------------------
方法名称为:wait , 方法返回值类型为:void 方法参数类型()
------------------------------------
方法名称为:equals , 方法返回值类型为:boolean 方法参数类型(java.lang.Object)
------------------------------------
方法名称为:toString , 方法返回值类型为:java.lang.String 方法参数类型()
------------------------------------
方法名称为:hashCode , 方法返回值类型为:int 方法参数类型()
------------------------------------
方法名称为:getClass , 方法返回值类型为:java.lang.Class 方法参数类型()
------------------------------------
方法名称为:notify , 方法返回值类型为:void 方法参数类型()
------------------------------------
方法名称为:notifyAll , 方法返回值类型为:void 方法参数类型()
===========================================
构造方法:com.rocklei123.spring.transaction.transferAccount.entity.User(java.lang.String,double,)
构造方法:com.rocklei123.spring.transaction.transferAccount.entity.User()
===========================================
7.方法的反射
1)如何获取某个方法
方法的名称和方法的参数列表才能唯一决定某个方法
2)方法反射的操作
method.invoke(对象,参数列表)
1 | package com.rocklei123.reflect; |
8.通过Class,Method来认识泛型的本质
- 编译之后集合的泛型是去泛型化的
- Java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译就无效了
- 验证:我们可以通过方法的反射来操作,绕过编译
1 | package com.rocklei123.reflect; |
9.参考
慕课网 https://www.imooc.com/learn/199
Java基础之—反射(非常重要) https://blog.csdn.net/sinat_38259539/article/details/71799078