Java反射机制
在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Class类将一个类的组成封装成各个属性,并实现了各个getXxx()方法。
public static void getInfo(Class cls) throws NoSuchMethodException {
//构造方法
cls.getConstructor();
//包含的方法
cls.getMethods();
//包含的属性
cls.getFields();
//实现的接口
cls.getInterfaces();
//包含的Annotation
cls.getAnnotations();
//内部类
cls.getDeclaredClasses();
//外部类
cls.getDeclaringClass();
//获取类名
cls.getName();
//获取包名
cls.getPackage();
//获取修饰符
cls.getModifiers();
}
创建Person类
public class Person {
private String name;
private int age;
private String address;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private void setAddress(String address){
this.address = address;
}
}
各种操作实现:
-
通过反射获取类的三种方式
/**
* 通过反射获取类的三种方式
* @throws ClassNotFoundException
*/
private void getClassWay() throws ClassNotFoundException {
Class cls = null;
cls = Person.class; //1
cls = new Person().getClass(); //2
cls = Class.forName("com.example.apple.Person"); //3
}
-
利用newInstance创建对象
/**
* 利用newInstance创建对象:调用的类必须有无参的构造器
* @param cls
*/
private void getInstance(Class cls){
try {
Person person = (Person) cls.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
-
获取类所有方法
/**
* 获取类所有方法(private修饰除外)
* @param cls
*/
public static void getMethods(Class cls){
Method[] methods = cls.getMethods();
for(Method method : methods){
System.out.println(method.getName());
}
}
-
获取类声明的方法
/**
* 获取类声明的方法
* @param cls
*/
public static void getAllMethods(Class cls){
Method[] methods = cls.getDeclaredMethods();
for(Method method : methods){
System.out.println(method.getName());
}
}
-
获取指定方法
/**
* 获取指定方法
* @param cls
* @throws NoSuchMethodException
*/
public static void getMethod(Class cls) throws NoSuchMethodException {
//第一个参数是方法名,后面参数依次是方法的参数类型
Method method = cls.getDeclaredMethod("setName",String.class);
System.out.println(method);
}
-
执行方法
/**
* 执行方法
* @param cls
*/
public static void invokMethod(Class cls) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Person person = (Person) cls.newInstance();
Method method = cls.getDeclaredMethod("setAddress",String.class);
//可以访问对象的私有方法
method.setAccessible(true);
//invoke参数第一个,要调用方法的对象,后面对应为各个参数
method.invoke(person,"北京海淀区");
}
-
操作属性值
/**
* 操作属性值
* @param cls
*/
public static void getFileds(Class cls) throws NoSuchFieldException, IllegalAccessException {
//获取字段
Field[] fields = cls.getFields();
Field field = cls.getDeclaredField("address");
field.setAccessible(true);
//获取指定对象指定属性的值
Person person = new Person();
//设置指定对象的值
field.set(person,"北京海淀区");
}
-
获取构造方法
public static void getConstructor(Class cls) throws NoSuchMethodException {
//获取所有构造方法
Constructor[] constructors = cls.getConstructors();
//获取所有构造方法(包括私有)
cls.getDeclaredConstructors();
//获取指定参数对应类型的构造方法
cls.getDeclaredConstructor(String.class,Integer.class);
}