- Java的反射机制实在运行状态中,对于一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的方法和属性,这种动态获取的获取信息以及动态调用对象的方法的功能称为java语言的反射
- 想要解剖一个类,必须先要获取该类的字节码文件对象(类的信息都存储在这里面了呢),解剖使用的就是Class类对象
1.1 获取Class类型的对象
// 方式一: 获取一个类字节码文件对象
Person person = new Person("henson");
Class aClass = person.getClass();
// System.out.println(aClass);
// 方式二:
Class bClass = Person.class;
// 方式三:
// java.lang.ClassNotFoundException: Person
Class cClass = Class.forName("com.cskaoyan.reflection.Person");
1.2 通过反射获取类构造方法&&创建对象
// 1. 获取类的字节码文件对象
Class aClass = Class.forName("com.cskaoyan.reflection.Person");
//获取public类型的
Constructor[] constructors = aClass.getConstructors();
//获取所有类型的
Constructor[] declaredConstructors = aClass.getDeclaredConstructors();
for (Constructor c : declaredConstructors) {
System.out.println(c);
}
// 如何通过 Construtor 对象生成对象
// T newInstance(Object... initargs) Object[] 参数个数可以是任意个(包括0个)
// Uses the constructor represented by this Constructor object to create and initialize
// a new instance of the constructor's declaring class, with the specified initialization parameters.
// 获取无参构造方法
Constructor constructor = aClass.getConstructor();
Object o = constructor.newInstance();
System.out.println(o);
// 获取两个参数的构造方法(public)
// Constructor<T> getConstructor(Class<?>... parameterTypes)
//获取私有的方法;需要设置Access
Constructor constructor1 = aClass.getDeclaredConstructor(String.class, int.class);
// void setAccessible(boolean flag)
//Set the accessible flag for this object to the indicated boolean value.
constructor1.setAccessible(true);
// 自动装箱 拆箱 把基本数据自动装箱成相应的引用数据类型 Integer
Object allen = constructor1.newInstance("Allen", 18);
System.out.println(allen);
}
通过反射获取成员变量并使用
// 1. 获取字节码文件对象
Class aClass = Class.forName("com.cskaoyan.reflection.Person");
// 2. 通过字节码文件对象获取属性(域)
// 获取父类和自己公共的成员属性和静态属性(public)
Field[] fields = aClass.getFields();
// 获取自己定义的所有的成员属性和静态属性(包括private)
Field[] declaredFields = aClass.getDeclaredFields();
/*
Person person = new Person();
person.name = "Trista"; //public
person.age = 18; //private
*/
Object o = aClass.newInstance();
System.out.println(o);
Field nameField = aClass.getField("name");
// 第一参数:表示要对哪个对象进行赋值
// 第二参数:该对象的该属性要新赋予的值
nameField.set(o, "Trista");
System.out.println(o);
// NoSuchFieldException: age,private类型
Field age = aClass.getDeclaredField("age");
age.setAccessible(true);
age.set(o, 18);
System.out.println(o);
}
获取成员方法
//1 .获取字节码文件对象
Class aClass = Class.forName("com.cskaoyan.reflection.Person");
// 获取父类和子类中公共的成员方法和静态方法
Method[] methods = aClass.getMethods();
// 获取该类中声明的所有成员方法和静态方法
Method[] declaredMethods = aClass.getDeclaredMethods();
Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class);
declaredConstructor.setAccessible(true);
Object jenny = declaredConstructor.newInstance("Jenny", 18);
// Object invoke(Object obj, Object... args)
// 获取某个方法
Method getAge = aClass.getMethod("getAge");
//相当于对象.方法,(有参数,再后面加上)
Object invoke = getAge.invoke(jenny); // 自动拆箱
System.out.println(invoke);
//如果是private方法,设置Access
Method show = aClass.getDeclaredMethod("show");
show.setAccessible(true);
Object result = show.invoke(jenny);
System.out.println(result);
}
注:
通过反射访问类:
private Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
Person(String name) {
this.name = name;
}
private static void show() {
System.out.println("show self");
}
public int getAge() {
return age;
}
网友评论