框架:半成品軟體,可以在框架的基礎上進行軟體開發,簡化編碼
反射:將類的各個組成部分封裝為其他物件,這就是反射機制
好處: * 可以在程式執行過程中,操作這些物件。 * 可以解耦,提高程式的可擴充套件性。
一、基本概念
在反射機制中,還可以透過反射得到一個類的完整結構,這就需要使用 java.lang.reflect 包中的以下幾個類:
Constructor:表示類中的構造方法Field:表示類中的屬性Method:表示類中的方法
這三個類都是 AccessibleObject 類的子類:
interface China{ public static final String NATIONAL = "China"; public static final String AUTHOR = "Java"; public void sayChina();//定義無參的抽象方法 public String sayHello(String name,int age);//定義有參的抽象方法}class Person implements China{ private String name; private int age; public Person(){ } public Person(String name){//宣告有一個引數的構造方法 this.name = name; } public Person(String name,int age){ this(name); this.setAge(age); } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } @Override public void sayChina() { System.out.println("作者:" + AUTHOR + ",國籍:" + NATIONAL); } @Override public String sayHello(String name, int age) { return name + "你好!我今年" + age + "歲了!"; }}
二、取得所實現的全部介面要取得一個類所實現的全部介面,必須使用 Class 類中的 getInterfaces() 方法,該方法定義:
public Class[] getInterfaces()
getInterfaces() 方法返回一個 Class 類的物件陣列,之後直接利用 Class 類中的 getName() 方法輸出即可。
public class Root{ public static void main(String[] args) { Class<?> c1 = null;//宣告 Class物件 try{ c1 = Class.forName("Person"); }catch (ClassNotFoundException e){ e.printStackTrace(); } Class<?> c[] = c1.getInterfaces();//取得實現的全部介面 for (int i=0;i<c.length;i++){ System.out.println("實現的介面名稱:" + c[i].getName());//輸出介面名稱 } }}
因為介面是類的特殊形式,而且一個類可以實現多個介面,所以此時以 Class 陣列的形式將全部的介面物件返回,並利用迴圈的方式將內容依次輸出
三、取得父類一個類可以實現多個介面,但是隻能繼承一個父類,所以要想取得一個類的父類,可以直接使用 Class 類中的 getSuperclass() 方法,該方法定義:
public Class<? super T> getSuperclass()
getSuperclass() 方法返回的是 Class 例項,和之前得到的介面一樣,可以透過 getName() 方法取得名稱。
public class Test{ public static void main(String[] args) { Class<?> c1 = null; try { c1 = Class.forName("Person"); }catch (ClassNotFoundException e){ e.printStackTrace(); } Class<?> c2 = c1.getSuperclass();//取得父類資訊 System.out.println("父類名稱:" + c2.getName()); }}
Person 類在編寫時沒有明確地繼承一個父類,所以預設繼承 Object 類
四、取得全部構造方法要取得一個類中的全部構造方法,必須使用 Class 類中的 getConstructors() 方法。
1.取得 Person 類的全部構造方法
import java.lang.reflect.Constructor;public class Test{ public static void main(String[] args) { Class<?> c1 = null; try { c1 = Class.forName("Person"); }catch (ClassNotFoundException e){ e.printStackTrace(); } Constructor<?> con[] = c1.getConstructors();//得到全部構造方法 for (int i=0;i<con.length;i++){ System.out.println("構造方法:" + con[i]); } }}
2.取得一個類的全部構造方法
import java.lang.reflect.Constructor;import java.lang.reflect.Modifier;public class Test{ public static void main(String[] args) { Class<?> c1 = null; try { c1 = Class.forName("Person"); }catch (ClassNotFoundException e){ e.printStackTrace(); } Constructor<?> con[] = c1.getConstructors();//得到全部構造方法 for (int i=0;i<con.length;i++){ Class<?> p[] = con[i].getParameterTypes();//列出構造中的引數型別 System.out.print("構造方法:"); int mo = con[i].getModifiers();//取出許可權 System.out.print(Modifier.toString(mo) + " ");//還原許可權 System.out.print(con[i].getName());//輸出構造方法名稱 System.out.print("("); for (int j=0;j<p.length;j++){ System.out.print(p[j].getName() + " arg" + i); if (j<p.length-1){//列印引數型別,判斷是否要輸出“,” System.out.print(","); } } System.out.println("){}"); } }}
五、取得全部方法要取得一個類中的全部方法,可以使用 Class 類中的 getMethods() 方法,該方法返回一個 Method 類的物件陣列。該方法的常用方法:
取得一個類的全部方法定義:
import java.lang.reflect.Method;import java.lang.reflect.Modifier;public class Test{ public static void main(String[] args) { Class<?> c1 = null; try { c1 = Class.forName("Person"); }catch (ClassNotFoundException e){ e.printStackTrace(); } Method m[] = c1.getMethods();//取得全部的方法 for (int i=0;i<m.length;i++){ Class<?> r = m[i].getReturnType();//取出方法的返回值型別 Class<?> p[] = m[i].getParameterTypes();//得到全部的引數型別 int xx = m[i].getModifiers();//得到方法的修飾符 System.out.print(Modifier.toString(xx) + " ");//還原修飾符 System.out.print(r.getName() + " ");//得到方法名稱 System.out.print(m[i].getName());//取得方法名稱 System.out.print("("); for (int x=0;x<p.length;x++){ System.out.print(p[x].getName() + " " + "arg" + x);//輸出引數 if (x<p.length-1){ System.out.print(",");//判斷是否輸出"," } } Class<?> ex[] = m[i].getExceptionTypes();//得到全部的異常丟擲 if (ex.length>0){ System.out.print(") throws ");//輸出“) throws” }else { System.out.print(")"); } for (int j=0;j<ex.length;j++){ System.out.print(ex[j].getName());//輸出異常資訊 if (j<ex.length-1){ System.out.print(","); } } System.out.println(); } }}
開發工具就是利用了反射的原理
六、取得全部屬性在反射操作中也同樣可以取得一個類中的全部屬性,有兩種不同的操作:
得到實現的介面或父類中的公共屬性:public Field[] getFields() throws SecurityException得到本類中的全部屬性:public Field[] getDeclareDeclaredFields() throws SecurityException
上述方法返回的都是 Field 的陣列,每一個 Field 物件表示類中的一個屬性,而要想取得屬性的進一步資訊,需要使用:
取得 Person 類中的屬性
import java.lang.reflect.Field;import java.lang.reflect.Modifier;public class Test{ public static void main(String[] args) { Class<?> c1 = null; try { c1 = Class.forName("Person"); }catch (ClassNotFoundException e){ e.printStackTrace(); } {//普通程式碼塊 Field f[] = c1.getDeclaredFields();//取得本類屬性 for (int i=0;i<f.length;i++){ Class<?> r = f[i].getType();//取得屬性的型別 int mo = f[i].getModifiers();//得到修飾符數字 String priv = Modifier.toString(mo);//取得屬性的修飾符 System.out.print("本類屬性:"); System.out.print(priv + " ");//輸出修飾符 System.out.print(r.getName() + " ");//輸出屬性型別 System.out.print(f[i].getName());//輸出屬性名稱 System.out.println(";");//換行 } } System.out.println("==========================="); { Field f[] = c1.getFields();//取得父類公共屬性 for (int i=0;i<f.length;i++){ Class<?> r = f[i].getType();//取得屬性的型別 int mo = f[i].getModifiers();//取得修飾符數字 String priv = Modifier.toString(mo);//取得屬性修飾符 System.out.print("公共屬性:"); System.out.print(priv + " ");//輸出修飾符 System.out.print(r.getName() + " ");//輸出引數型別 System.out.print(f[i].getName());//輸出屬性名稱 System.out.println(";"); } } }}
作者:南淮北安連結:https://juejin.cn/post/6923479418119651342來源:掘金