## 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专题五:持久化