反射定義
所謂反射村生,可以理解為在運行時期獲取對象類型信息的操作冰木。
傳統(tǒng)的編程方法要求程序員在編譯階段決定使用的類型沿量,但是在反射的幫助下浪慌,編程人員可以動態(tài)獲取這些信息,從而編寫更加具有可移植性的代碼朴则。
嚴(yán)格地說权纤,反射并非編程語言的特性,因為在任何一種語言都可以實現(xiàn)反射機制乌妒,但是如果編程語言本身支持反射汹想,那么反射的實現(xiàn)就會方便很多。
Class類的使用
要弄懂反射撤蚊,首先要了解Class類的使用
package com.saictest.demo.controller;
public class SystemUser {
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
@Test
public void testc() throws Exception {
SystemUser sysUser=new SystemUser();
Class<?> cls = Class.forName("com.saictest.demo.controller.SystemUser");
System.out.println(cls);
System.out.println(SystemUser.class);
System.out.println(sysUser.getClass());
System.out.println(SystemUser.class.getClass());
}
打印結(jié)果
class com.saictest.demo.controller.SystemUser
class com.saictest.demo.controller.SystemUser
class com.saictest.demo.controller.SystemUser
class java.lang.Class
-
一切皆對象古掏,我們創(chuàng)建的每一個類也都是對象,即類本身是java.lang.Class類的實例對象侦啸,但是這些對象都不需要new出來槽唾,因為java.lang.Class類的構(gòu)造方法是私有的
所以我們創(chuàng)建SystemUser 也是Class類的實例對象 -
獲取Class對象(即 類類型 / 類型類)
獲取有三種方式
- Class c1 = SystemUser.class
已知類名,直接通過類名.class獲取該類的類型類- Class c1 = sysUser.getClass()
已知對象光涂,通過sysUser.getClass()獲取該類的類型類- Class c1 = Class.forName("com.saictest.demo.controller.SystemUser")
動態(tài)加載庞萍,通過Class.forName動態(tài)加載獲取類型類
Java中一切都是對象,我們一般所使用的對象都直接或間接繼承自O(shè)bject類忘闻。Object類中包含一個方法名叫g(shù)etClass()钝计,利用這個方法就可以獲得一個實例的類型類。類型類指的是代表一個類型的類齐佳,因為一切皆是對象私恬,類型也不例外,在Java使用類型類來表示一個類型炼吴。所有的類型類都是Class類的實例本鸣,也就是我們常說的獲取class對象。
從上面代碼可以看出來sysUser是SystemUser的實例缺厉,所以我們可以通過sysUser.getClass()獲取它的類型類永高。
-
引申
從上面代碼里我們還看到一個奇怪的地方SystemUser.class.getClass(),為什么類型類還可以調(diào)用getClass方法呢提针,不是說只有實例對象才可以調(diào)用嗎命爬?這是因為SystemUser.class也是Class類的實例,所以可以調(diào)用getClass方法,調(diào)用結(jié)果返回類型類為class java.lang.Class辐脖。
System.out.println(c1==c2)饲宛,返回結(jié)果為true
可以通過類的類類型創(chuàng)建該類的對象實例,即通過c1或c2創(chuàng)建SystemUser的實例嗜价。
SystemUserstu = (SystemUser)c1.newInstance();//前提是必須要有無參的構(gòu)造方法艇抠,因為該語句會去調(diào)用其無參構(gòu)造方法幕庐。該語句會拋出異常。