柚子快報激活碼778899分享:Java之反射
柚子快報激活碼778899分享:Java之反射
目錄
反射
定義
主要用途
反射相關(guān)的類
Class類中【獲得類相關(guān)方法】
Class類中【獲得類中屬性相關(guān)的方法】?
Class類中【獲得類中注解相關(guān)的方法】?
?
Class類中【獲得類中構(gòu)造器相關(guān)的方法】?
Class類中【獲得類中方法相關(guān)的方法】?
獲得Class對象
代碼示例1
代碼示例2
反射的優(yōu)缺點
反射
定義
Java的反射(re?ection)機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意方法和屬性,既然能拿到那么,我們就可以修改部分類型信息;這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為java語言的反射(re?ection)機(jī)制。
主要用途
1.動態(tài)地創(chuàng)建類的實例:在運(yùn)行時根據(jù)類的全限定名創(chuàng)建對象。 2.檢查類的結(jié)構(gòu):獲取類的成員變量、方法、構(gòu)造器等信息。 3.調(diào)用方法:在運(yùn)行時動態(tài)地調(diào)用對象的方法。 4.訪問和修改私有字段:即使在類定義中字段是私有的,也可以通過反射來訪問和修改。?
反射相關(guān)的類
類名用途Class類代表類的實體,在運(yùn)行的Java應(yīng)用程序中表示類和接口Filed類代表類的成員變量/類的屬性Method類代表類的方法Constructor類代表類的構(gòu)造方法
Class類
Class類代表類的實體,在運(yùn)行的Java應(yīng)用程序中表示類和接口 .
Java文件被編譯后,生成了.class文件,JVM此時就要去解讀.class文件 ,被編譯后的Java文件.class也被JVM解析為一個對象,這個對象就是java.lang.Class,這樣當(dāng)程序在運(yùn)行時,每個.class文件就最終變成了Class類對象的一個實例。我們通過Java的反射機(jī)制應(yīng)用到這個實例,就可以去獲得甚至去添加改變這個類的屬性和動作,使得這個類成為一個動態(tài)的類。
Class類中【獲得類相關(guān)方法】
方法用途getClassLoader()獲得類的加載器getDeclaredClasses()返回一個數(shù)組,數(shù)組中包含該類的所有類和和接口類的對象(包括私有的)forName(String className)根據(jù)類名返回類的對象newInstance()創(chuàng)建類的實例getName()獲得類的完整路徑名字
Class類中【獲得類中屬性相關(guān)的方法】?
方法用途getField(String name)獲得某個公有的屬性對象getFields()獲得所有公有的屬性對象getDeclaredField(String name)獲得某個屬性對象getDeclaredFields()獲得所有屬性對象
Class類中【獲得類中注解相關(guān)的方法】?
方法用途getAnnotation(Class annotationClass)返回該類中與參數(shù)匹配的公有注解對象getAnnotations()返回該類中所有的公有注解對象getDeclaredAnnotaion(Class annotationClass)返回該類中與參數(shù)類型匹配的所有注解對象getDeclaredAnnotations()返回該類所有的注解對象
Class類中【獲得類中構(gòu)造器相關(guān)的方法】?
方法用途getConstructor(Class>... parameterTypes)獲得該類中與參數(shù)類型匹配的公有構(gòu)造方法getConstructors()獲得該類的所有公有構(gòu)造方法getDeclaredConstructor(Class>... parameterTypes)獲得該類中與參數(shù)類型匹配的構(gòu)造方法getDeclaredConstructors()獲得該類所有構(gòu)造方法
Class類中【獲得類中方法相關(guān)的方法】?
方法用途getMethod(String name,Class>... parameterTypes)獲得該類某個公有的方法geMethods()獲得該類所有公有的方法getDeclaredMethod(String name,Class>... parameterTypes)獲得該類某個方法getDeclaredMethds()獲得該類所有方法
獲得Class對象
反射的第一步是獲取代表某個類的Class對象??梢酝ㄟ^多種方式獲取Class對象,最常見的是:
1.使用Class.forName(String className)靜態(tài)方法,如果類名在類的路徑中,則通過該類的全限定名(包括包名)來獲取Class對象。注意,這種方式會拋出ClassNotFoundException。 2.使用.class語法,在編譯時就已經(jīng)確定。 3.調(diào)用對象的getClass()方法,在運(yùn)行時確定對象的實際類型。
代碼示例1
class Student{
//私有屬性name
private String name = "bit";
//公有屬性age
public int age = 18;
//不帶參數(shù)的構(gòu)造方法
public Student(){
System.out.println("Student()");
}
private Student(String name,int age) {
this.name = name;
this.age = age;
System.out.println("Student(String,name)");
}
private void eat(){
System.out.println("i am eat");
}
public void sleep(){
System.out.println("i am pig");
}
private void function(String str) {
System.out.println(str);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
//Class對象 只有一個
public static void main(String[] args) {
Class> c1;
try {
c1 = Class.forName("reflectdemo.Student");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
Class> c2;
c2 = Student.class;
Student student = new Student();
Class> c3 = student.getClass();
System.out.println(c1.equals(c2));
System.out.println(c1.equals(c3));
System.out.println(c3.equals(c2));
}
}
代碼示例2
class Student{
//私有屬性name
private String name = "bit";
//公有屬性age
public int age = 18;
//不帶參數(shù)的構(gòu)造方法
public Student(){
System.out.println("Student()");
}
private Student(String name,int age) {
this.name = name;
this.age = age;
System.out.println("Student(String,name)");
}
private void eat(){
System.out.println("i am eat");
}
public void sleep(){
System.out.println("i am pig");
}
private void function(String str) {
System.out.println(str);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class ReflectDemo {
//如何通過反射 實例化對象
public static void reflectNewInstance() {
Class> c1;
try {
c1 = Class.forName("reflectdemo.Student");
Student student = (Student) c1.newInstance();
System.out.println(student);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
// 反射私有的構(gòu)造方法 屏蔽內(nèi)容為獲得公有的構(gòu)造方法
public static void reflectPrivateConstructor() {
Class> c1;
try {
c1 = Class.forName("reflectdemo.Student");
Constructor
(Constructor)c1.getDeclaredConstructor(String.class,int.class);
con.setAccessible(true);
Student student = con.newInstance("zhangsan",18);
System.out.println(student);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
// 反射私有屬性
public static void reflectPrivateField() {
Class> c1;
try {
c1 = Class.forName("reflectdemo.Student");
Field field = c1.getDeclaredField("name");
field.setAccessible(true);
Student student = (Student) c1.newInstance();
field.set(student,"wangwu");
System.out.println(student);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
// 反射私有方法
public static void reflectPrivateMethod() {
Class> c1;
try {
c1 = Class.forName("reflectdemo.Student");
Method method = c1.getDeclaredMethod("function",String.class);
method.setAccessible(true);
Student student = (Student) c1.newInstance();
method.invoke(student,"我是一個參數(shù)");
//System.out.println(student);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
//reflectNewInstance();
//reflectPrivateConstructor();
//reflectPrivateField();
reflectPrivateMethod();
}
}
反射的優(yōu)缺點
優(yōu)點
1. 對于任意一個類,都能夠知道這個類的所有屬性和方法;
? ? 對于任意一個對象,都能夠調(diào)用它的任意一個方法。
2. 增加程序的靈活性和擴(kuò)展性,降低耦合性,提高自適應(yīng)能力。 3. 反射已經(jīng)運(yùn)用在了很多流行框架如:Struts、Hibernate、Spring 等等。
缺點
1.反射會破壞封裝性,使代碼難以理解和維護(hù)。 2.反射通常比直接代碼調(diào)用慢,因為它涉及到類型檢查等動態(tài)解析。 3.濫用反射可能導(dǎo)致安全問題,如訪問或修改不應(yīng)該被訪問的私有成員。
柚子快報激活碼778899分享:Java之反射
相關(guān)閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。