Github:https://github.com/imyiren/java-base-ilss
1. 認(rèn)識Class類
Java在運行的時候辕漂,會為對象維護(hù)一個運行時的類型標(biāo)識,虛擬機(jī)運行Java程序的時候用它來選擇相應(yīng)類的方法執(zhí)行吴超。
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()); //基本數(shù)據(jù)類型的class Class cls3 = int.class; System.out.println(cls3.getName());
-
Class.forName(String)
會拋出checked exception(已檢查異常):ClassNotFoundException
-
Class.forName(String)
給的類需要包含包鲸阻,包也是類名的一部分 - 雖然基本數(shù)據(jù)類型不是類跋涣,但是
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)
- 動態(tài)創(chuàng)建類的實例
integer.getClass().newInstance()
- 此處會拋出
InstantiationException
陈辱,
- 此處會拋出
-
Class
類的一些方法-
T newInstance()
實例化一個此對象,此外方法在Java9以后已經(jīng)不推薦被使用 -
Field[] getFields()
返回這個對象的Field
數(shù)組细诸,包括了本類和父類的公有域 -
Field[] getDeclaredFields()
返回Field
數(shù)組性置,包括這個類的全部域,如果對象沒有域揍堰,則返回一個長度為0的數(shù)組 -
Method[] getMethods()
返回這個對象的Method
數(shù)組鹏浅,包括了本類的和父類繼承的公有方法 -
Method[] getDeclaredMethods()
返回Method
數(shù)組嗅义,包括這個類的全部方法,但是不包括父類繼承的方法隐砸。 -
Constructor[] getConstructors()
返回這個對象的Constructor
數(shù)組之碗,包含所有共有構(gòu)造器 -
Constructor[] getDeclaredConstructors()
返回這個對象的Constructor
數(shù)組,包含所有構(gòu)造器
-
2. 探索java.lang.reflect
包
做一個控制臺答應(yīng)類信息的以demo吧季希。
java.lang.reflect
包中包括了幾個比較重要的類:Field
褪那、Method
、Constructor
式塌、Modifier
-
Field
在《Java核心技術(shù)卷I》中叫做域博敬,簡單理解就是對應(yīng)我們對應(yīng)的對象,變量峰尝。 -
Method
方法操作的對象-
Class getReturnType()
返回一個返回類型的一個對象
-
-
Constructor
構(gòu)造器操作對象 -
Modifier
修飾語操作的對象-
static String toString(int modifiers)
返回對應(yīng)位置中的的字符串 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數(shù)組(Field沒有) -
Class[] getParameterTypes()
返回一個類型參數(shù)類型的數(shù)組(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();
// 開始打印構(gòu)造器
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) {
// 得到所有的構(gòu)造器
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 + "(");
// 構(gòu)造器參數(shù)
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大家有沒有想到偏窝,我們用的一些框架,里面某些地方是怎么實現(xiàn)的武学。就如數(shù)據(jù)庫框架的字段對應(yīng)祭往,就可以的通過Field的getName方法取得與之匹配。
- 其實反射也是Java類的使用火窒,但是要深入理解它的意義和用途還是挺難的硼补。
- 未完待續(xù)。