Java 反射干货解析
图示分析
反射机制代码详解
定义:Person类
package reflex_01;
public class Person {
private String name;
public int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
定义:主类
package reflex_01;
public class ReflexDemo {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
String className="reflex_01.Person";
//通过该类的名称,加载对应的字节码文件,并封装成字节码文件对象ca
Class ca=Class.forName(className);//会抛出一个类不存在异常
System.out.println(ca);
//获取newInstance()可以创建字节码对象所表示的类的实例
Object obj = ca.newInstance();
/**
* 通常被反射的类都会提供空参数的构造方法
* 没有对应的构造方法 会报InstantiationException(实例化异常)
* 如果有提供,但权限不够 会报IllegalAccessException (非法访问异常)
*/
System.out.println(obj);
/**
* 底层原理:
* 1.加载Person类,并将Person封装成字节码文件对象
* 2.通过new创建Person对象
* 3.调用构造方法对对象初始化
* Person p=new Person();
*/
}
}
获取构造方法
package reflex_01;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflexDemo1 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
String className="reflex_01.Person";
//通过该类的名称,加载对应的字节码文件,并封装成字节码文件对象ca
Class ca=Class.forName(className);//会抛出一个类不存在异常
//获取指定的共有构造器 获取Person两个参数String int类型的构造方法
Constructor cons = ca.getConstructor(String.class,int.class); // 此构造方法是私有的,因此无法访问NoSuchMethodException
//获取共有的无参构造
// Constructor con = ca.getConstructor();
// Constructor cans1 = ca.getDeclaredConstructor(String.class, int.class); //同样会有权限问题出现
//有了构造器对象之后,可以用构造器对象来初始化类对象
Object o = cons.newInstance("张三", 23);
// Object o = cans1.newInstance("张三", 23);
// Object o1 = con.newInstance();
// System.out.println(o1); //Person{name='null', age=0}
System.out.println(o); //Person{name='张三', age=23}
}
}
字段获取
package reflex_01;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class FieldGet {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
String className="reflex_01.Person";
//通过该类的名称,加载对应的字节码文件,并封装成字节码文件对象ca
Class ca=Class.forName(className);//会抛出一个类不存在异常
//获取公共的字段 age 是public的
Field field = ca.getField("age");
//获取本类中已有的成员 name是私有的
Field name = ca.getDeclaredField("name");
Method method = ca.getMethod("getName");
Method method1 = ca.getDeclaredMethod("setName", String.class);
//总结: getXXX都是获取类中公共的成员
// getDeclaredXXX 获取本类中已有的成员 包括private修饰的成员方法及其变量
//构造方法等其他字段权限如果出现问题,那么只能使用暴力访问,解除权限检查
System.out.println(name);
System.out.println(field);
}
}
暴力访问机制
package reflex_02;
import java.lang.reflect.Field;
public class AxcessibleDemo {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
String className="reflex_01.Person";
//通过该类的名称,加载对应的字节码文件,并封装成字节码文件对象ca
Class ca=Class.forName(className);
Field field=ca.getDeclaredField("name" );
//对其进行值的设置,必须先有对象
Object obj = ca.newInstance();
//通过查找父类的setAccessibleObject的方法 setAccessible(true);
field.setAccessible(true);//取消权限检查 暴力访问
field.set(obj,"流星雨"); //IllegalAccessException name字段是私有的
System.out.println(field.get(obj));
}
}