## Java專題九(1):反射
[TOC]
### 9.1.Class類
Class類包括以下元素:
- 類名ClassName
- 構造器Constructor
- 成員變量Field
- 成員方法Method
- 父類Superclass
```
package org.it;
public class FileTools implements Comparable{
public String clsName = "FileTools";
String path;
public void setPath(String path){
System.out.println("[method invoke] setPath");
this.path = path;
}
public String getPath(){
return getPath0();
}
private String getPath0(){
return path;
}
@Override
public int compareTo(Object o) {
return 0;
}
}
```
#### 9.1.1.類名
| 方法 | 說明 | 例子 |
| --- | --- | --- |
| String getName() | 獲取類名,包括包名限定符 | org.it.FileTools
| String getCanonicalName() | 獲取符合Java規范的類名,包括包名限定符 | org.it.FileTools
| String getSimpleName() | 獲取簡單的類名,不包括包名限定符 | FileTools |
#### 9.1.2.構造器Constructor
| 方法 | 說明 | 例子 |
| --- | --- | --- |
| Constructor<?>[] getConstructors() | 獲取所有構造器,| class java.lang.Object |
| Constructor<?>[] getDeclaredConstructors() | 獲取所有構造器,包括本類public, protected, default(package),private構造方法| - |
| Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException| 在getConstructors()返回的列表中,根據構造方法形參查找構造方法,需要手動捕獲'java.lang.NoSuchMethodException' 異常 | - |
| Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) throws NoSuchMethodException| getDeclaredConstructors()返回的列表中,根據構造方法形參查找構造方法,需要手動捕獲'java.lang.NoSuchMethodException' 異常 | - |
#### 9.1.3.成員變量Field
| 方法 | 說明 | 例子 |
| --- | --- | --- |
| Field[] getFields() | 獲取所有成員變量,只包括public成員 | [clsName] |
| Field[] getDeclaredFields() throws NoSuchFieldException| 獲取所有成員變量,包括本類public, protected, default(package),private成員變量,不包括繼承的成員變量 | [clsName, path] |
| Field getField(String name) throws NoSuchFieldException| 在getFields()返回的列表中,根據變量名查找成員變量,需要手動捕獲'java.lang.NoSuchFieldException' 異常 | - |
| Field getDeclaredField(String name) | 在getDeclaredFields()返回的列表中,根據變量名查找成員變量,需要手動捕獲'java.lang.NoSuchFieldException' 異常 | - |
#### 9.1.4.成員方法Method
| 方法 | 說明 | 例子 |
| --- | --- | --- |
| Method[] getMethods() | 獲取所有成員變量,包括本類定義的和繼承自父類、接口的public方法 | 見FileTools.class.getMethods() |
| Method[] getDeclaredMethods() | 獲取所有成員變量,包括本類public, protected, default(package),private成員方法,不包括繼承的成員方法 | 見FileTools.class.getDeclaredMethods() |
| Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException | getMethods()返回的列表中,根據方法名和形參類型查找成員方法,需要手動捕獲'java.lang.NoSuchMethodException' 異常 | - |
| Method getDeclaredMethod(String name, Class<?>... parameterTypes) | getDeclaredMethods()返回的列表中,根據方法名和形參類型查找成員方法,需要手動捕獲'java.lang.NoSuchMethodException' 異常 | - |
- FileTools.class.getMethods():
```
0 = {Method@602} "public int org.it.FileTools.compareTo(java.lang.Object)"
1 = {Method@603} "public java.lang.String org.it.FileTools.getPath()"
2 = {Method@604} "public void org.it.FileTools.setPath(java.lang.String)"
3 = {Method@605} "public final void java.lang.Object.wait() throws java.lang.InterruptedException"
4 = {Method@606} "public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException"
5 = {Method@607} "public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException"
6 = {Method@608} "public boolean java.lang.Object.equals(java.lang.Object)"
7 = {Method@609} "public java.lang.String java.lang.Object.toString()"
8 = {Method@610} "public native int java.lang.Object.hashCode()"
9 = {Method@611} "public final native java.lang.Class java.lang.Object.getClass()"
10 = {Method@612} "public final native void java.lang.Object.notify()"
11 = {Method@613} "public final native void java.lang.Object.notifyAll()"
```
- FileTools.class.getDeclaredMethods():
```
0 = {Method@628} "public int org.it.FileTools.compareTo(java.lang.Object)"
1 = {Method@629} "public java.lang.String org.it.FileTools.getPath()"
2 = {Method@630} "private java.lang.String org.it.FileTools.getPath0()"
3 = {Method@631} "public void org.it.FileTools.setPath(java.lang.String)"
```
#### 9.1.5.父類Superclass
| 方法 | 說明 | 例子 |
| --- | --- | --- |
| Class<? super T> getSuperclass() | 獲取直接父類,不包括接口 | class java.lang.Object |
#### 9.1.6.判斷對象是否為數組
| 方法 | 說明 | 例子 |
| --- | --- | --- |
| boolean isArray()| 判斷對象是否為數組|- |
```
Object obj = new int[]{1, 2, 3};
obj.getClass().isArray(); // 這里返回true
```
### 9.2.Constructor類
Constructor類包括以下元素:
- 構造方法形參parameterTypes
- 構造方法拋出的異常exceptionTypes
- 構造方法修飾符modifiers
```
Class cl = FileTools.class;
Constructor constructor = cl.getDeclaredConstructors()[0];
try {
FileTools fts = (FileTools)constructor.newInstance(new Object[]{});
System.out.println(fts == null);
}catch (Exception e){
e.printStackTrace();
}
```
輸出:
```
false
```
### 9.3.Field類
Field類包括以下元素:
- 成員變量名name
- 成員變量類型type
- 成員變量修飾符modifiers
| 方法 | 說明 | 例子 |
| --- | --- | --- |
| String getName()| 成員變量名name|- |
| Class<?> getType()| 獲取成員變量類型type|- |
| int getModifiers()| 獲取成員變量修飾符modifiers|- |
### 9.4.Method類
Method類包括以下元素:
- 方法名name
- 方法返回類型returnType
- 方法形參parameterTypes
- 方法拋出的異常exceptionTypes
- 方法修飾符modifiers
| 方法 | 說明 | 例子 |
| --- | --- | --- |
| String getName()| 獲取方法名name|- |
| Class<?> getReturnType()| 獲取方法返回類型returnType|- |
| Class<?>[] getParameterTypes()| 獲取方法形參parameterTypes|- |
| Class<?>[] getExceptionTypes()| 獲取方法拋出的異常exceptionTypes|- |
| int getModifiers()| 獲取方法修飾符modifiers|- |
| Object invoke(Object obj, Object... args)| 根據形參args調用對象obj方法|- |
```
Class cl = FileTools.class;
Constructor constructor = cl.getDeclaredConstructors()[0];
try {
FileTools fts = (FileTools)constructor.newInstance(new Object[]{});
Method[] methods = cl.getMethods();
for (Method method: methods) {
if (method.getName() == "setPath"){
method.invoke(fts, "/usr/bin");
}
}
System.out.println("path:" + fts.getPath());
}catch (Exception e){
e.printStackTrace();
}
```
輸出:
```
[method invoke] setPath
path:/usr/bin
```
### 9.5.java.lang.reflect.Array類
| 方法 | 說明 | 例子 |
| --- | --- | --- |
| int getLength(Object array)| 獲取數組對象的長度,這里沒法通過length成員直接判斷|- |
| Object get(Object array, int index)| 獲取數組指定下標的元素|- |
在不知道數組對象由什么類型的元素組成的話,這個類非常有用,用法如下:
```
Object obj = new int[]{1, 2, 3};
int len = Array.getLength(obj);
for(int i=0; i<len; i++){
Object obj0 = Array.get(obj, i);
if (obj0 instanceof Integer){
int a = (int)obj0;
}else if (obj0 instanceof Float){
float a = (float)obj0;
}
// ...
}
```
- JavaCook
- Java專題零:類的繼承
- Java專題一:數據類型
- Java專題二:相等與比較
- Java專題三:集合
- Java專題四:異常
- Java專題五:遍歷與迭代
- Java專題六:運算符
- Java專題七:正則表達式
- Java專題八:泛型
- Java專題九:反射
- Java專題九(1):反射
- Java專題九(2):動態代理
- Java專題十:日期與時間
- Java專題十一:IO與NIO
- Java專題十一(1):IO
- Java專題十一(2):NIO
- Java專題十二:網絡
- Java專題十三:并發編程
- Java專題十三(1):線程與線程池
- Java專題十三(2):線程安全與同步
- Java專題十三(3):內存模型、volatile、ThreadLocal
- Java專題十四:JDBC
- Java專題十五:日志
- Java專題十六:定時任務
- Java專題十七:JavaMail
- Java專題十八:注解
- Java專題十九:淺拷貝與深拷貝
- Java專題二十:設計模式
- Java專題二十一:序列化與反序列化
- 附加專題一:MySQL
- MySQL專題零:簡介
- MySQL專題一:安裝與連接
- MySQL專題二:DDL與DML語法
- MySQL專題三:工作原理
- MySQL專題四:InnoDB存儲引擎
- MySQL專題五:sql優化
- MySQL專題六:數據類型
- 附加專題二:Mybatis
- Mybatis專題零:簡介
- Mybatis專題一:配置文件
- Mybatis專題二:映射文件
- Mybatis專題三:動態SQL
- Mybatis專題四:源碼解析
- 附加專題三:Web編程
- Web專題零:HTTP協議
- Web專題一:Servlet
- Web專題二:Cookie與Session
- 附加專題四:Redis
- Redis專題一:數據類型
- Redis專題二:事務
- Redis專題三:key的過期
- Redis專題四:消息隊列
- Redis專題五:持久化