Java反射—初探反射基礎
Github:https://github.com/ilssio/java-base-ilss
1. 認識Class類
Java在執行的時候,會為物件維護一個執行時的型別標識,虛擬機器執行Java程式的時候用它來選擇相應類的方法執行。
Java可以通過一個特定的類來訪問這些類資訊,這個類就是Class。
- 獲取Class的幾種方式
注意:Integer integer = 100; Class cls = integer.getClass(); // 類名 System.out.println(cls.getName()); // 通過對類名來獲取物件 Class cls1 = Class.forName("java.lang.Integer"); System.out.println(cls1.getName()); //其他方法 Class cls2 = Integer.class; System.out.println(cls2.getName()); Class cls4 = Integer[].class; System.out.println(cls4.getName()); //基本資料型別的class Class cls3 = int.class; System.out.println(cls3.getName());
-
Class.forName(String)
會丟擲checked exception(已檢查異常):ClassNotFoundException
-
Class.forName(String)
給的類需要包含包,包也是類名的一部分 - 雖然基本資料型別不是類,但是
int.class
是一個類。 - Integer[].class 的類名不是
java.lang.Integer
.而是[Ljava.lang.Integer
,Double.class
的為[Ljava.lang.Double
;另外int[].class
是[I
-
- Class類實際是一個泛型類
Integer.class
就是一個Class<Integer>
- Class類可以用 == 判斷是否為同類,如:
if(integer.getClass() == Integer.class)
- 動態建立類的例項
integer.getClass().newInstance()
- 此處會丟擲
InstantiationException
,
- 此處會丟擲
-
Class
類的一些方法-
T newInstance()
例項化一個此物件,此外方法在Java9以後已經不推薦被使用 -
Field[] getFields()
返回這個物件的Field
陣列,包括了本類和父類的公有域 -
Field[] getDeclaredFields()
返回Field
陣列,包括這個類的全部域,如果物件沒有域,則返回一個長度為0的陣列 -
Method[] getMethods()
返回這個物件的Method
陣列,包括了本類的和父類繼承的公有方法 -
Method[] getDeclaredMethods()
返回Method
陣列,包括這個類的全部方法,但是不包括父類繼承的方法。 -
Constructor[] getConstructors()
返回這個物件的Constructor
陣列,包含所有共有構造器 -
Constructor[] getDeclaredConstructors()
返回這個物件的Constructor
陣列,包含所有構造器
-
2. 探索java.lang.reflect
包
做一個控制檯答應類資訊的以demo吧。java.lang.reflect
包中包括了幾個比較重要的類:Field
、Method
、Constructor
、Modifier
-
Field
在《Java核心技術卷I》中叫做域,簡單理解就是對應我們對應的物件,變數。 -
Method
方法操作的物件-
Class getReturnType()
返回一個返回型別的一個物件
-
-
Constructor
構造器操作物件 -
Modifier
修飾語操作的物件-
static String toString(int modifiers)
返回對應位置中的的字串 static boolean isAbstract(int modifiers)
static boolean isFinal(int modifiers)
static boolean isInterface(int modifiers)
static boolean isNative(int modifiers)
static boolean isPrivate(int modifiers)
static boolean isProtected(int modifiers)
static boolean isPublic(int modifiers)
static boolean isStatic(int modifiers)
static boolean isStrict(int modifiers)
static boolean isSynchronized(int modifiers)
static boolean isVolatile(int modifiers)
-
-
Field Method Constructor
的一些方法-
Class getDeclaringClass()
返回定義中的Class物件 -
int getModifier()
返回一個修飾符的值 -
String getName()
得到名字的字串 -
Class[] getExceptionTypes()
得到丟擲的異常型別的Class陣列(Field沒有) -
Class[] getParameterTypes()
返回一個型別引數型別的陣列(Field沒有)
-
- demo程式碼如下:
package io.ilss.reflection;
import java.lang.reflect.*;
import java.util.Scanner;
/**
* className ReflectionTest
* description ReflectionTest
*
* @author feng
* @version 1.0
* @date 2019-01-24 21:25
*/
public class ReflectionTest {
public static void main(String[] args) {
String name;
if (args.length > 0) {
name = args[0];
} else {
Scanner in = new Scanner(System.in);
System.out.println("Enter class name (e.g. java.util.Date): ");
name = in.next();
}
try {
// 利用String name 得到類
Class cls = Class.forName(name);
// 得到父類
Class superCls = cls.getSuperclass();
// 得到類的修飾 "public final "
String modifiers = Modifier.toString(cls.getModifiers());
if (modifiers.length() > 0) {
System.out.print(modifiers + " ");
}
System.out.print("class " + name);
// 判斷除Object外的父類存在與否
if (superCls != null && superCls != Object.class) {
System.out.print(" extends " + superCls.getName());
}
System.out.print("{\n");
// 開始列印域
printFields(cls);
System.out.println();
// 開始列印構造器
printConstructors(cls);
System.out.println();
// 開始列印方法
printMethods(cls);
System.out.println();
System.out.println("}");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.exit(0);
}
private static void printFields(Class cls) {
// 得到這個類的所有域
Field[] fields = cls.getDeclaredFields();
// 便利輸出
for (Field field : fields) {
// 分別得到修飾 型別 名字的字串
String modifiers = Modifier.toString(field.getModifiers());
Class type = field.getType();
String name = field.getName();
//輸出
System.out.print(" ");
if (modifiers.length() > 0) {
System.out.print(modifiers + " ");
}
System.out.println(type.getName() + " " + name + ";");
}
}
private static void printConstructors(Class cls) {
// 得到所有的構造器
Constructor[] constructors = cls.getDeclaredConstructors();
for (Constructor constructor : constructors) {
String name = constructor.getName();
String modifiers = Modifier.toString(constructor.getModifiers());
System.out.print(" ");
if (modifiers.length() > 0) {
System.out.print(modifiers + " ");
}
System.out.print(name + "(");
// 構造器引數
Class[] paramTypes = constructor.getParameterTypes();
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0) System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
}
private static void printMethods(Class cls) {
Method[] methods = cls.getDeclaredMethods();
for (Method method : methods) {
String modifiers = Modifier.toString(method.getModifiers());
String name = method.getName();
// 返回型別
Class retType = method.getReturnType();
System.out.print(" ");
if (modifiers.length() > 0) {
System.out.print(modifiers + " ");
}
System.out.print(retType.getName() + " " + name + "(");
// 方法的形參
Class[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(paramTypes[i].getName());
}
System.out.println(");");
}
}
}
- 通過上面的demo大家有沒有想到,我們用的一些框架,裡面某些地方是怎麼實現的。就如資料庫框架的欄位對應,就可以的通過Field的getName方法取得與之匹配。
- 其實反射也是Java類的使用,但是要深入理解它的意義和用途還是挺難的。
- 未完待續。
相關文章
- 【Java 反射學習】Java 反射基礎Java反射
- [Java 反射學習] Java 反射基礎Java反射
- Java基礎 —— 反射Java反射
- [Java基礎]反射Java反射
- Java 反射基礎Java反射
- Java-基礎-反射Java反射
- Java基礎(十一)——反射Java反射
- Java基礎(十八)反射Java反射
- Java基礎系列—Java反射Java反射
- 【Java反射】Java 泛型基礎Java反射泛型
- java基礎 -反射筆記Java反射筆記
- 反射基礎反射
- Java基礎——深入理解反射Java反射
- JAVA基礎學習篇之反射Java反射
- Java基礎之反射機制(續)Java反射
- Java重點基礎:反射機制Java反射
- 基礎篇:深入解析JAVA反射機制Java反射
- Java基礎對反射知識總結Java反射
- java框架基礎技術之--------反射機制Java框架反射
- java基礎語法(三十九)—反射機制(二)Java反射
- Java程式設計基礎28——反射&JDK新特性Java程式設計反射JDK
- Java反射Java反射
- Java——反射Java反射
- Java 反射Java反射
- 【Go進階—基礎特性】反射Go反射
- Java基礎加強筆記——測試、反射、註解Java筆記反射
- java基礎:深入理解Class物件與反射機制Java物件反射
- Java 反射 APIJava反射API
- Java 反射原理Java反射
- 20201209——java反射Java反射
- Java的反射Java反射
- 【Java面試指北】反射(1) 初識反射Java面試反射
- PHP DIY 系列------基礎篇:3. 反射PHP反射
- 淺析Java反射--JavaJava反射
- java EE開發之Servlet第十一課:反射基礎三JavaServlet反射
- java反射構建物件和方法的反射呼叫Java反射物件
- Java反射與hook混用反射某支付的方法Java反射Hook
- Java安全基礎之Java反射機制和ClassLoader類載入機制Java反射