Java 反射基础

 一、小案例引入反射

Biglnteger.class 
Eliauk VCS 
public 
public 
public 
Proxy.class 
a 
u:] Mtwm.java 
u:] Wechat.java 
u:] Alipay.java 
README 
src com.eliauk.common.reflect.testOI TestClazz •s main(StringO) : 
TestClazz.java 
u:] BankCard.java 
37. 
61 
static void pay "g) { 
wc . payonline(); 
static void pay(AIiPay { 
ap.payonline(); 
static void pay(8ankCard p;) { 
bc . payonline(); 
• fitfE— 
public static void main (String[] { 
string payType = 
.equa1s(payType)) { 
pay(new Ali Pay()); 
else if .equaIs(payType)) { 
pay(new 
else .equaIs(payType)) { 
pay(new Bankcard()); 
else { 
System. out . 
// fi*äiHE-N-FQ, 
public static void m) { 
m. payonline(); 
@throws Exception 
public static void main (String[] args) throws Exception 
String 
Class O 
Obi ect 
met hod 
met hod 
- "com.eliauk.common.reflect.testßl . Alipay"; 
pay T ype 
. > clazz = Class.forName(payType); 
clazz.newlnstance(); 
method = 
. i nvoke (obj ) ;

 

二、反射的概念 

炸 緝 斜 入 导 0 的 
一 0 例 0 弁 0 了 
0 @园能生冉体0辰到 
0 土 = 1 芸 
歡 罕 码 0 00 式 
的 司 以 在 六 上 的 实 到 种 芸 
忙 式 
式 生 芩 0 帮 0 
0 2055 00 
」 AVA 反 射 机 制 是 在 过 
态 中 , 对 于 任 意 一 个 类 孬 都 能 够 知 道 这 个 类 的 所 有 属 性 和 方 法 ; 对 于 任 意 一 个 对 象 , 
都 能 够 调 用 它 的 任 意 方 法 和 庙 性 ; 这 种 动 态 获 取 信 息 以 及 动 态 调 用 对 象 方 法 的 功 能 称 湖 ava 语 言 的 反 射 机 ll. 
在 编 译 后 产 生 字 节 码 文 件 的 时 候 , 类 加 载 器 子 系 统 涯 过 二 进 制 字 节 流 , 负 夤 从 文 件 糸 统 加 载 cla + 文 件 · 
在 执 行 程 序 (java-exe) 时 候 , 将 字 节 遍 文 件 读 入 」 VM 中 “ . > 这 个 过 程 叫 做 类 的 加 然 后 在 内 存 中 对 应 创 建 一 个 ja 姹 」 ang . Class 对 象 . > 
这 个 对 象 会 被 放 入 字 节 码 信 息 中 , 这 个 Class 对 就 厨 应 加 载 那 个 字 节 码 信 息 , 这 个 对 象 将 被 作 为 程 序 访 问 方 法 区 中 的 这 个 类 的 各 种 数 据 的 外 
部 接 口 。 
所 以 : 我 们 可 以 涌 过 这 个 对 象 看 到 类 的 结 沟 , 这 个 对 象 就 好 像 是 一 面 镜 子 , 透 过 子 看 到 类 的 各 种 信 息 , 我 们 形 象 的 称 之 为 反 射 
这 种 看 透 " class 的 能 力 (the ability Of the program to examine itself) 被 称 为 introspection ( 内 省 、 内 观 、 反 省 ) 。 Reflection 和 
introspection 是 常 被 并 提 的 两 个 术i乩 
说 明 : 任 运 行 期 间 , 如 
如 果 没 有 被 加 载 , JVM 根 据 类 的 名 称 找 到 clas 
」 的 Class 对 象 是 否 已 被 加 载 · 
一 目 某 个 类 型 的 Cla 寸 象 已 被 加 载 到 内 存 , 就 可 以 它 来 产 生 该 类 型 的 
补 充 : 
动 态 语 膏 vs 静 态 语 言 
1 、 动 态 语 言 
是 一 类 在 运 行 时 可 L : 
.class2 亻 
访 问 该 文 件 的 入 囗 , 是 C SS 的 对 象 。 
其 结 构 的 言 : 例 如 新 的 函 数 、 对 象 、 甚 至 代 码 可 以 
《 被 引 进 , 已 有 的 函 数 可 被 删 除 或 是 其 他 结 构 上 的 变 化 。 通 俗 点 说 就 是 在 运 
行 时 代 码 可 以 根 据 臬 些 件 改 变 自 身 结 构 。 
主 要 动 态 语 言 : Object 
2 、 静 态 语 言 
与 动 态 浯 言 相 对 应 的 , 
C# 、 JavaScript 、 PHP 、 Python 、 Erlang ·

 

所以,Java不是动态语言,但是java可以称之为“准动态语言”。即Java有一定的动态性,可以利用反射机制、字节码操作 获得类似动态语言的特性。

Java的动态性让编程的时候更加灵活!

 

- myBase Desktop 
D •8 e. o •o •frtn 
A 
2020/3/5 
Exe cut i cm Engine 
j avant* 
(XXX.elass) 
Claß 
Program CMter 
Reg 
Method S tuk 
Java Virtual Machine Stack 
Native Mett•od 
Inte 
Native Method 
L i bra ry

 

  

三、Class类

面 向 对 象 思 维 : 万 事 万 物 皆 对 象 
涌 过 电 脑 类 。 可 以 得 到 具 体 的 
类 脑 类 的 对 象 ( 张 三 的 电 脑 实 例 ) 
有 了 对 象 以 后 就 可 以 获 取 对 象 的 
内 容 : 可 以 获 取 颜 色 属 性 , 还 可 
以 获 取 品 牌 属 性 
对 
类 : 申 脑 类 
共 同 特 点 
向 上 抽 取 形 成 一 个 " 类 " 
类 : 
方 法 
构 造 器 
Student* 的 字 节 码 文 件 
java-lang.Class* 
共 同 特 点 
向 上 抽 取 形 成 一 个 
构 造 器 
iMüCIass 类 , 可 以 得 到 具 休 
白 Cla “ 类 的 对 象 (Student 
字 节 码 信 息 ) , 得 到 了 Class 
类 的 对 象 以 后 就 可 以 获 取 对 
象 内 容 : 可 以 获 取 属 性 , 可 
法 , 可 以 获 取 构 造 
器 等 
戴 尔 
红 色 
张 三 的 电 葩 类 的 实 例 
Person 类 的 字 节 码 文 件 
李 四 的 电 脑 类 的 实 例 
想 要 获 取 红 色 : 电 葩 类 一 》 得 到 具 体 的 实 例 ( 对 象 〕 一 一 一 > 诵 i 寸 对 象 得 到 红 
想 要 获 取 性 : Class 类 .“》 得 到 具 体 的 实 例 ( 对 象 ) . “ 》 通 过 对 象 得 到 性

 

四、获取字节码信息的方式

package com.eliauk.common.reflect.testß2; 
public class Test { 
public static void main (StringC] args) throws Exception { 
// iMj$getCIass() 
Person p = new Person(); 
Class<? extends Person> pCIazzI 
System. out. println (pCIazzI); 
Class pCIazz2 
Person . class; 
System. out. println (pCIazz2); 
p. getCIass(); 
Class . formame( "corn . el i auk. comnon . refl ect . testu . Person" ) ; 
ClassQ> class3 
ys em.ou . prln n 
Test . class . getCIassLoader(); 
ClassLoader loader 
class4 = loader. common. reflect. testß2.Person"); 
System. out. printIn(cIass4); 
&& pCIazz2.equaIs(cIass3) && class3.equaIs(cIass4)); 
31

 

五、Class的具体实例

package com.ellauk.common. 
* @description 
* @author 
* @date 2e21*2k1ea 
@version VI . e 
public class Instances { 
public static void main (StringC] 
void 
Class 
Class 
Class 
intC] 
Person . class; 
Comparable. class; 
Override. class; 
arrl 
Class<? extends c4 
intC] art-2 
Class 
Class c6 
Class 
2. getCIass(); 
args) { 
. getCIass(); 
arrl 
&& c4 
// true. 
int . class; 
void . class; 
System. out. printIn(c7); 
// void 
34

  

六、获取运行时类的完整结构

1. 获得实例

Eliauk N PCS 
src com.eliauk.common.reflect.test02 
I package com.eliauk.common.reflect . testß2; 
S import java. lang. reflect . Constructor; 
* @description 
Test01 
* @author 
* @date 2e21*2k1ea 
@version VI . e 
public class Testßl { 
public static void main (StringC] 
args ) 
Class cl = Student.class; 
System. out. println 
System. out. println( 
ConstructorC] constructors 
for (Constructor constructor : 
t h rows 
Exception 
TestOI [Java Application] 121 (2021*2É IOS 
class com.eliauk.common.reflect.testß2.Student 
public com.eliauk.common.reflect.testu.Student 
public com.eliauk.common . reflect . testß2. Student (double,double) 
public com.eliauk.common.reflect.testu . Student 
private com.eliauk.common . reflect. testß2.Student(int 
com.eliauk.common . refl ect . testß2. Student (int , doubl e) 
pntected com.eliauk.common.reflect.testu . Student 
public com.eliauk.common . Student (double,double) 
public com.eliauk.common . reflect . testß2 .Student() 
public com.eliauk.common . reflect . testß2 .Student (double,double) 
private 
Student 
Student 
com.eliauk.common . reflect . testß2. Student (i nt ) 
I . getConstructors ( ) ; 
constructors) { 
System. out. (constructor); 
System. out. println(" 
ConstructorC] declaredConstructors 
for (Constructor constructor : declaredConstructors) { 
System. out. (constructor); 
System. out. println(" 
cl . getConstructor(); 
Constructor constructor 
System. out. (constructor); 
System. out. println( 
cl . getConstructor (double. class, 
Constructor constructor-2 
System. out. ntln (constructor-2); 
System. out. println( 
Csno=ø, 
Csno=ø, 
height=ø.ø, weight=ø.ø, score=ø.ß] 
height=152.2, weight=12ø.I, score=ø.ß] 
double. class) ; 
cl . getDecIaredConstructor(int . class); 
Constructor declaredConstructor 
System. out. ntln (declaredConstructor); 
System. out. println( 
Object 
constructor. newlnstance(); 
System. out. ntln (obj ) ; 
Object 
constructor-2. newlnstance(12ø.I, 
System. out. ntln (obi 2); 
152.2);

 

2. 获得属性并赋值

4 
package com.eliauk.cornmon.reflect . testø2; 
import java.Iang.refIect.FieId; 
import java. lang. reflect.modifier; 
@description 
* @author 
* @date 2e21*2k1ea 
@version vl.ß 
public class Testß2 { 
public static void main (StringC] 
Class cl = Student. class; 
args) throws Exception { 
Test02 [Java Application] 121 (2021*2É IOS 
public double com.eliauk.common.reflect.testu Student. score 
public java.Iang.String com.eliauk.common.reflect.testß2.Person.name 
private int com.eliauk.common.reflect.testß2.Student.sno 
el i auk. common . refl ect . testß2. Student . height 
double com. 
pntected double com.eliauk.common.reflect.testu . Student.weight 
public double com.eliauk.common.reflect.testß2.Student.score 
public double com.eliauk.common.reflect .Student.score 
private int com.eliauk.common . reflect. testu .Student.sno 
private 
FieldC] fields - 
for (Field field 
I.getFieIds(); 
. fields) 
System. out. pri ntln (field); 
System. out. print In 
FieldC] declaredFieIds 
cl . getDecIaredFieIds(); 
for (Field field 
: declaredFieIds) { 
System. out. println (field); 
System. out. println(" 
Field score 
System. out. println(score); 
System. out. println( 
Student Csno=ø, 
height=ø.ø, 
weight=ø.ø, 
s core=98.ß] 
Field sno 
I ("sno"); 
System. out. println(sno); 
System. out. println( 
String snoName 
sno.getName(); 
System. out. ntln (snoNarne); 
sno.getType(); 
type 
String snoType 
type . getName(); 
System. out. println (snoT ype); 
int 
sno. getmodifi ers ( ) ; 
System. out. (snomodifiers); 
System. out. pri ntl n (modifi er. toString (snomodifi ers ) ) ; 
System. out. println( 
Object 
cl. newlnstance(); 
score. set (obi, 98); // 
System. out. ntln (obj ) ;

  

七、获取方法和调用方法

Eliauk N PCS 
src com.eliauk.common.reflect.test02 Test03 
puDLIC c Lass lestes t 
public static void args) throws Exception { 
Class cl = Student.class; 
cl . getMethods ( ) ; 
Method[] methods 
for (Method method : methods) { 
System. out. ntln (method); 
System. out. println(" 
cl . getDecIaredMethods(); 
Method[] decIaredMethods 
for (Method methad decIaredMethads) { 
System. out. ntln (method); 
System. out. println(" 
public 
public 
public 
public 
public 
public 
public 
public 
public 
public 
public 
public 
public 
public 
public 
public 
Test03 [Java Application] 121 (2021*2Ê 
java.Iang.String com.eliauk.common.reFIect.testB2.Student.toString() 
java.Iang.String com.eliauk.common.reFIect.testB2.Student.showInFo() 
java. lang.String com.eliauk.common . . testB2 .Student.showInFo(int) 
void com.eliauk.common.refIect.testB2.Student.myMethod() throws iava.Iang.RuntimeException 
void com.eliauk.common.reFIect.testB2.Person.sIeep() 
Final 
void java.Iang.Object.wait() thm:nvs java .Iang.InterruptedException 
Final 
void thm:nvs java .Iang.InterruptedException 
Final native void java.Iang.Object.wait(Iong) thmnws java .Iang.InterruptedException 
boolean java.Iang.Object.equaIs(java.Iang.Object) 
native int java.Iang.Object.hashCode() 
Final native java.Iang.CIass java.Iang.Object.getCIass() 
Final native void java.Iang.Object.notiFy() 
Final native void java.Iang.Object.notifyAII() 
java.Iang.String com.eliauk.common.refIect.testB2.Student.toString() 
java. lang.String com.eliauk.common . . testB2 .Student.showInFo() 
java. lang.String com.eliauk.common . . testB2. Student.showlnfo(int) 
cl . getMethod ( " ) ; 
Met h od 
shawln+a 
System. out. ntln (showlnfo); 
cl . getMethod ( " showlnfo" , 
Met h od 
shawInFa2 
System. out. ntln (showInf02); 
System. out. println( 
cl . aredMethod ( 
Met h od 
work 
System. out. ntln (work); 
System. out. pri ntln (work. getName()); 
int. class) ; 
int . class) ; 
vate 
void com.eliauk.common.reFIect.testB2.Student.work( 
public void com.eliauk.common.refIect.testB2.Student.myMethod() throws iava.Iang.RuntimeException 
void com.eliauk.common.reFIect.testB2.Student.happy() 
pmntected int com.eliauk.common.reFIect.testB2. Student .getSno() 
public java.Iang.String 
com.eliauk.common . refl ect . testB2. Student . showlnfo() 
public java.Iang.String 
com.eliauk.common . refl ect . testB2. Student . showlnfo(int ) 
private void com.eliauk.common.reflect .Student 
. work(int) 
work 
pri vate 
void 
@com.eliauk.common . refl ect . testB2. MyAnnotation (val u e=hel ) 
System. out. pri ntl n (Modifi er. toString (work. getnodifiers ( ) ) ) ; 
System. out. ntln ( ) ) ; 
work. getParameterTypes ( ) ; 
parameterTypes 
for classl 
. parameterTypes) { 
System. out. println(classl); 
System. out. println(" 
Met h od 
mw•lethad = cl . 
Annotation[] annotations = mw•lethad .getAnnotations(); 
for (Annotation annotation : 
annotations) { 
System. out. (annotation) ; 
exceptionTypes = my'•lethod .getExceptionTypes(); 
: exception Types) { 
for classl 
System. out. println(classl); 
c ass 
nava. ang. un 1 me xcep 1 cn 
student Mylnte#ace 
(SOURCE) 
Object 
cl. newlnstance(); 
my'•lethad . invoke(abj ) ;

  

八、获取类的接口、所在包、注解

package com.eliauk.common . reflect. testß2; 
import java. lang. annotation.Annotation; 
@description 
Test04 [Java Application] 121 (202% 
Enter—face com.eliauk.common.reflect.testß2..'•Iy 
Interface 
interface java.io.SeriaIizabIe 
package com.eliauk.common . reflect . testß2 
com.eliauk.common . refl ect . testß2 
@com.eliauk.common . reflect . testß2. myAnnotation (val ue=hel IoStudent ) 
* @author 
* @date 2e21*2k1ea 
@version VI . e 
public class Testß4 { 
public static void main (StringC] 
Class cl = Student.class; 
args) { 
ClassC] interfaces 
cl . get Interfaces ( ) ; 
for (Class classl 
. interfaces) { 
System. out. println(classl); 
System. out. println(" 
Class super-class 
I.getSupercIass(); 
super-class . get Interfaces ( ) ; 
ClassC] super-interfaces 
for (Class classl 
. superlnterfaces) { 
System. out. println(classl); 
System. out. println(" 
cl . getpackage(); 
Package packagel 
System. out. println (packagel); 
System. out. ntln (packagel . getName()); 
System. out. println( 
Annotation(] annotations 
. getAnnotations( 
for (Annotation annotation : 
annotations) { 
System. out. println (annotation);

  

九、关于反射的面试题

问题1:创建Persion对象,用new 还是 用反射?

即什么情况下用反射?

提现程序的 扩展性、动态性。

 

问题2:反射是否破坏了面向对象的封装性?

封装是为了提高代码的安全性,即保护代码。

而反射是为了提高程序的动态性,而并非是为了破坏封装性。

举例:男厕所、 女厕所...

 

posted @ 2021-02-18 14:40  冬雷zz  阅读(39)  评论(0)    收藏  举报