通过反射查看类的信息
Java程序中许多对象在运行时都会出现两种类型:编译时类型和运行时类型
例如:Person p = new Student();
编译类型为:Person
运行类型为:Student
为了解决这种问题,有两种方式:
- 假设在编译时和运行时都完全知道类型的具体信息,在这种情况下,可以先使用instanceof 运算符进行判断
- 编译时无法知道对象和类属于那些类,程序只能依靠运行时信息来发现该对象和类的真实信息,这就必须通过反射
1. 获得 Class 对象
java程序中获得 Class 对象有三种方式
- 使用Class 类的forName(String clazzName)静方法。必须是完整包名。
- 调用某个类的class属性来获取该类的 Class 对象。
- 调用某个对象的getClass() 方法。
2. 从 Class 对象中获取信息
具体使用查阅API文档,下面以一个例子来说明
package com.example;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* Created by zhoujian on 2017/4/5.
*/
public class ClassTest {
private ClassTest() {
System.out.println("执行无参构造函数");
}
public ClassTest(String name) {
System.out.println("执行有参构造函数");
}
public void method() {
System.out.println("执行无参method方法");
}
public void method(String str) {
System.out.println("执行有参method方法");
}
public static void main(String[] args) {
//获取Class对象
Class<ClassTest> aClass = ClassTest.class;
//获取Class对象所对应类的全部构造器
Constructor<?>[] constructors = aClass.getDeclaredConstructors();
System.out.println("ClassTest的全部构造器如下:");
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
//获取Class对象所对应类的全部public构造器
Constructor<?>[] cons = aClass.getConstructors();
System.out.println("-----------------------------------");
System.out.println("ClassTest的全部public构造器如下:");
for (Constructor<?> c : cons) {
System.out.println(c);
}
//获取Class对象所对应类的全部public方法
Method[] methods = aClass.getMethods();
System.out.println("-----------------------------------");
System.out.println("ClassTest的全部public方法如下:");
for (Method method : methods) {
System.out.println(method);
}
//获取Class对象所对应类的指定方法
try
{
Method meth = aClass.getMethod("method", String.class);
System.out.println("-----------------------------------");
System.out.println("ClassTest里带一个字符串参数的method方法:"+meth);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
运行结果如下:
3. Java8 新增的方法参数反射
package com.example;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;
/**
* Created by zhoujian on 2017/4/3.
*/
public class TextA
{
public void rep(String string, List<String> list)
{
}
public static void main(String[] args) {
Class<TextA> aClass = TextA.class;
try {
//获取带有两个参数的 rep方法
Method rep = aClass.getMethod("rep", String.class, List.class);
//获取指定方法参数个数
int count = rep.getParameterCount();
System.out.println("rep方法参数个数:" + count);
//获取rep 方法的所有参数信息
Parameter[] parameters = rep.getParameters();
int index = 1;
for (Parameter parameter : parameters) {
//方法返回该类的class文件中是否包含了方法的形参名信息
System.out.println("----第" + index++ + "个参数信息---");
System.out.println("参数名:" + parameter.getName());
System.out.println("形参类型:" + parameter.getType());
System.out.println("泛型类型:" + parameter.getParameterizedType());
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}