問題三連
反射是什麼?反射可以用來幹什麼?反射是在哪些場景下使用的,如何用?
能夠分析類能力的程序稱爲反射!
反射機制可以用來
1.在運行時分析類的能力。
2.在運行時查看對象,例如:編寫一個toString()方法供所有的類使用(反射可以拿到所有的變量,私有也可以獲取)。
3.實現通用的數組操作代碼。
4.利用Method 對象,這個對象很像C++中的函數指針。
動態操作Java代碼的程序,大量應用於JavaBeans中,大量應用於開發工具上,比如對象點後出現的提示就是反射實現的。
在程序運行期間,Java運行時系統始終爲所有的對象維護一個被稱爲運行時的類型標識。
這個信息跟蹤着每個對象所屬的類,虛擬機利用運行時類型信息選擇相應的方法執行,
保存這些信息的類被稱爲Class。
Object 類中的 getClass()方法會返回一個Class 類型的實例。
最常用的Class方法就是getName,這個方法將返回類的全路徑名稱。
調用靜態方法forName()獲取類名對應的Class對象。
Class class=Class.forName("com.xx.xxx");
Class 類實際上是一個泛型類,它將已經抽象的概念更加複雜化,
在大多數實際問題中,可以忽略類型參數,使用原始的Class類。
newInstance()方法,可以用來動態的創建一個類的實例。
它默認調用無參構造方法來創建實例,假如沒有默認的構造方法就會拋出異常!
利用反射可以分析類的結構,通過Field、Method和Constructor 分別用於描述類的域、方法和構造器。
這三個類都有一個叫做 getName()方法,用來返回項目的名稱。
Field 類有一個 getType()方法,用來返回描述域所屬類型的Class對象。
Method 和 Constructor 類有能夠報告參數類型的方法,它將返回一個整型數值,用不同的位開關描述 public static修飾符。
Modifier類中有 isPublic、isPrivate、isFinal 判斷方法或者構造器是否是 public、private和final的,toString()方法可以將修飾符打印出來。
下面來一個類,可以輸入Java裏面已經有的類全路徑名稱,來打印出他的方法。
package com.wavewave.demo.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;
/**
* @author wavewave
* @CreateDate: 2020/4/13 1:51 PM
* @Description:
* @Version: 1.0
*/
public class Test {
public static void main(String[] args) {
String name;
if (args.length > 0) {
name = args[0];
} else {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入類名稱");
name = scanner.next();
}
try {
Class cl = Class.forName(name);
Class superCl = cl.getSuperclass();
String modifiers = Modifier.toString(cl.getModifiers());
if (modifiers.length() > 0) {
System.out.print(modifiers + " ");
}
System.out.print("class " + name);
if (superCl != null && superCl != Object.class) {
System.out.print(" extends " + superCl.getName());
}
System.out.print("\n{\n");
printConstructors(cl);
System.out.println();
printMethods(cl);
System.out.println();
printFields(cl);
System.out.println("}");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private static void printConstructors(Class cl) {
Constructor[] constructors = cl.getDeclaredConstructors();
for (Constructor c : constructors) {
String name = c.getName();
System.out.print(" ");
String modifiers = Modifier.toString(c.getModifiers());
if (modifiers.length() > 0) {
System.out.print(modifiers + " ");
}
System.out.print(name + "(");
Class[] parameterTypes = c.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
if (i > 0) {
System.out.print(", ");
}
System.out.print(parameterTypes[i].getName());
}
System.out.println(");");
}
}
private static void printMethods(Class cl) {
Method[] methods = cl.getDeclaredMethods();
for (Method m : methods) {
Class returnType = m.getReturnType();
String name = m.getName();
System.out.println(" ");
String modifiers = Modifier.toString(m.getModifiers());
if (modifiers.length() > 0) {
System.out.print(modifiers + " ");
}
System.out.println(returnType.getName() + " " + name + "(");
Class[] parameterTypes = m.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
if (i > 0) {
System.out.print(",");
}
System.out.print(parameterTypes[i].getName());
}
System.out.println(");");
}
}
private static void printFields(Class cl) {
Field[] fields = cl.getDeclaredFields();
for (Field f : fields) {
Class type = f.getType();
String name = f.getName();
System.out.print(" ");
String modifiers = Modifier.toString(f.getModifiers());
if (modifiers.length() > 0) {
System.out.print(modifiers + " ");
}
System.out.print(type.getName() + " " + name + ";");
}
}
}
可以運行一下試試哦!