一 、应用场景
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法,常见的应用如下
- 逆向代码 ,例如反编译
- 与注解相结合的框架 例如Retrofit
- 单纯的反射机制应用框架 例如EventBus 2.x
- 动态生成类框架 例如Gson
二 、使用反射机制的步骤
- 第一步 是获得你想操作的类的 java.lang.Class 对象;
- 第二步 是调用诸如 getDeclaredMethods 的方法;
- 第三步 使用 反射API 来操作这些信息。
三 、反射机制的优缺点
可以实现动态创建对象和编译,体现出很大的灵活性(特别是在J2EE的开发中它的灵活性就表现的十分明显)。通过反射机制我们可以获得类的各种内容,进行了反编译。对于JAVA这种先编译再运行的语言来说,反射机制可以使代码更加灵活,更加容易实现面向对象,总结如下。
- 优点:运行期类型的判断,动态类加载,动态代理使用反射。
- 缺点:性能是一个问题,反射相当于一系列解释操作,通知jvm要做的事情,性能比直接的Java代码要慢很多
四 、实例
需求:设有一个类Person,使用反射机制获取该类的相关信息。
设计:实体类Person,存放个人的基本信息,测试类TestPerson使用反射机制获取Person类或其对象的封装信息。
4.1 Person类
package com.daiinfo.seniorjava.ken3.implement;
public class Person {
public String name;
public String sex;
String birthday;
/**
* 构造函数
*/
public Person(){
}
/**
* 构造函数
* @param name
*/
public Person(String name){
this.name=name;
}
/**
* 构造函数
* @param name
* @param sex
* @param birthday
*/
public Person(String name,String sex,String birthday) {
this.name=name;
this.sex=sex;
this.birthday=birthday;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
}
4.2 TestPerson类
package reflect.practise1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestPerson {
public static void getClassName() {
// 第一种方式使用getClass()方式
Person person = new Person("张三", "男", "2000-01-01");
Class<?> personC = person.getClass();
// 第二种方式 通过类的class属性
personC = Person.class;
// 第三种方式通过Class类的静态方法--forName()来实现
try {
personC = Class.forName("reflect.practise1.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
static void getClassInfo() {
Class<?> personC = null;
try {
personC = Class.forName("reflect.practise1.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
boolean isPrimitive = personC.isPrimitive();// 判断是否是基础类型
System.out.println("isPrimitive: " + isPrimitive);
boolean isArray = personC.isArray();// 判断是否是集合类
System.out.println("isArray: " + isArray);
boolean isInterface = personC.isInterface();// 判断是否是接口类
System.out.println("isInterface: " + isInterface);
boolean isEnum = personC.isEnum();// 判断是否是枚举类
System.out.println("isEnum: " + isEnum);
boolean isAnonymousClass = personC.isAnonymousClass();// 判断是否是匿名内部类
System.out.println("isAnonymousClass: " + isAnonymousClass);
boolean isAnnotationPresent = personC.isAnnotationPresent(Deprecated.class);// 判断是否被某个注解类修饰
System.out.println("isAnnotationPresent: " + isAnnotationPresent);
String className = personC.getName();// 获取class名字 包含包名路径
Package aPackage = personC.getPackage();// 获取class的包信息
String simpleName = personC.getSimpleName();// 获取class类名
int modifiers = personC.getModifiers();// 获取class访问权限
Class<?>[] declaredClasses = personC.getDeclaredClasses();// 内部类
System.out.println("内部类有" + declaredClasses.length);
Class<?> declaringClasses = personC.getDeclaringClass();// 外部类
System.out.println(declaringClasses);
System.out.println(aPackage + "\t" + simpleName + "\t" + modifiers);
}
static void getFields() {
Class<?> personC = null;
try {
personC = Class.forName("reflect.practise1.Person");
}catch(ClassNotFoundException e ) {
e.printStackTrace();
}
Field[] allFields = personC.getDeclaredFields();// 获取class对象的所有属性
System.out.println("**********");
for(int i= 0 ; i<allFields.length; i++) {
System.out.println(allFields[i]);
}
Field[] publicFields = personC.getFields();// 获取class对象的public属性
System.out.println("**********");
for(int i= 0 ; i < publicFields.length; i++) {
System.out.println(allFields[i]);
}
try {
Field nameField = personC.getDeclaredField("name");// 获取class指定属性
Field sexField = personC.getField("sex");// 获取class指定的public属性
System.out.println("****************");
System.out.println(nameField);
System.out.println("****************");
System.out.println(sexField);
} catch(NoSuchFieldException e) {
e.printStackTrace();
}
}
static void getMrthod() {
Class<?> personC = null;
try {
personC = Class.forName("reflect.practise1.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method[] methods = personC.getDeclaredMethods();// 获取class对象的所有声明方法
Method[] allMethod = personC.getMethods();// 获取class对象的所有方法 包括父类的方法
System.out.println("***********************");
System.out.println("The Person Class have the below methods:");
for(int i = 0 ; i< allMethod.length; i++) {
System.out.println(allMethod[i]);
}
}
static void getConstructors() {
Class<?> personC = null;
try {
personC = Class.forName("reflect.practise1.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Constructor<?>[] allConstructor = personC.getDeclaredConstructors();//获取class对象的所有声明构造函数
Constructor<?>[] publicConstructor = personC.getConstructors();//获取class对象public构造函数
System.out.println("***********************");
System.out.println("The Person Class have the below constructors:");
for(int i = 0 ; i< allConstructor.length; i++) {
System.out.println(allConstructor[i]);
}
}
public static void main(String[] args) throws ClassNotFoundException {
getClassName();
getClassInfo();
getFields();
getMrthod();
getConstructors();
}
}
4.3 执行结果
一些方法的详细说明参照【Java】用实例理解反射(一)