什么是反射?
在程序運行時動態(tài)加載類并獲取類的詳細信息,從而操作類或?qū)ο蟮膶傩院头椒ā1举|(zhì)是JVM得到class對象之后,再通過class對象進行反編譯,從而獲取對象的各種信息。
Java屬于先編譯再運行的語言,程序中對象的類型在編譯期就確定下來了,而當(dāng)程序在運行時可能需要動態(tài)加載某些類,這些類因為之前用不到,所以沒有被加載到JVM。通過反射,可以在運行時動態(tài)地創(chuàng)建對象并調(diào)用其屬性,不需要提前在編譯期知道運行的對象是誰。
反射的原理
反射最主要的一個類是Class對象。


反射相關(guān)的類:
java.lang.reflect.Constructor

java.lang.reflect.Field

java.lang.reflect.Method

反射的優(yōu)缺點:
優(yōu)點:在運行時獲得類的各種內(nèi)容,進行反編譯,對于Java這種先編譯再運行的語言,能夠讓我們很方便的創(chuàng)建靈活的代碼,這些代碼可以在運行時裝配,無需在組件之間進行源代碼的鏈接,更加容易實現(xiàn)面向?qū)ο蟆?/p>
缺點:反射會消耗一定的系統(tǒng)資源,因此,如果不需要動態(tài)地創(chuàng)建一個對象,那么就不需要用反射;
反射調(diào)用方法時可以忽略權(quán)限檢查,因此可能會破壞封裝性而導(dǎo)致安全問題。
反射應(yīng)用獲取實例對象
4種獲取實例對象的方法:
1.通過構(gòu)造函數(shù)來new一個對象;
TestClass testClass2 = new TestClass();
2.通過clone來克隆一個對象;
需要實現(xiàn)Cloneable接口,可分為深克隆和淺克隆。clone()后的新對象會復(fù)制原對象的屬性,但是并不會調(diào)用構(gòu)造函數(shù)。
public class TestClass implements Cloneable{
private String name;
private int age;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
TestClass testClass = new TestClass();
TestClass testClass1 = (TestClass) testClass.clone();
3.通過序列化反序列化來構(gòu)建一個對象;
需要被序列化的對象實現(xiàn)Serializable接口,不會調(diào)用構(gòu)造,反序列化回來的對象的屬性值與序列化之前一致,但是是一個新對象。
//序列化 xxx.ser序列化對象
TestClass t1 = new TestClass();
FileOutputStream fileOutputStream = new FileOutputStream("filePath/xxx.ser");
ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream);
outputStream.writeObject(t1);
outputStream.flush();
outputStream.close();
//反序列化
FileInputStream fileInputStream = new FileInputStream("filePath/xxx.ser");
ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
TestClass t2=(TestClass) inputStream.readObject();
inputStream.close();
4.通過反射來創(chuàng)建對象:a.通過Class類來創(chuàng)建,b.通過Constructor類來創(chuàng)建;
Class<?> classObject = Class.forName("com.test.TestClass");//完整徑
//獲取實例對象
TestClass test2 =(TestClass)classObject.newInstance();
Class<?> classObject = Class.forName("com.test.TestClass");//完整徑
//獲取實例對象
TestClass test3 =(TestClass)classObject.getConstructor().newInstance();