刚学了反射,整理一下
反射
java的反射机制是在运行状态中,对于任意一个对象,都可以获取这个类的所有属性和方法.
对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取信息以及动态调用对象方法的功能称为java的反射机制。反射就是通过class字节码文件对象,使用文件中的成员变量,成员方法,构造方法。
方式1 getClass方法
getClass()是Object类的方法
//创建对象
Stu s = new Stu();
//用对象调用Class对象
Class c = s.getClass();
方式2 通过class属性
类名.class
Class c = Stu.class;
方式3 Class类的forName方法
Clss c = Class.forName("com.ao.Stu");
Class类
-
public final class Class<T> extends Object implements Serializable, GenericDeclaration, Type, AnnotatedElement
-
Class类的对象表示正在运行的java应用程序中的类和接口的字节码文件对象
-
无构造方法
-
字节码文件是由jvm执行的,所以字节码文件对象也是由jvm构建的
* Class类: 不仅把字节码文件封装成了类类型,也把成员变量,构造方法,成员方法封装成类类型 * 成员变量:Field * 构造方法:Constructor * 成员方法:Method
获取构造方法对象
获取构造方法对象的方法都在Class类中
Constructor<T> getConstructor(类<?>... parameterTypes)
//返回指定公共构造方法的Constructor对象
Constructor<?>[] getConstructors()
//返回Constructor数组包含类的所有公共构造方法对象。
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
//返回任意一个指定构造方法的Constructor对象
Constructor<?>[] getDeclaredConstructors()
//返回Constructor数组包含类的所有构造方法对象。
使用构造方法对象
T newInstance(Object... initargs)
//使用 Constructor对象表示的构造函数创建实例
public void setAccessible(boolean flag)
//将此对象的accessible标志设置为指示的布尔值。 true的值表示反射对象应该在使用时抑制Java语言访问检查。 false的值表示反映的对象应该强制执行Java语言访问检查。
若用私有构造方法创建实例,需要先取消访问检查
获取成员变量对象
获取成员变量对象的方法都在Class类中
Field getField(String name)
//返回一个指定公共成员变量的对象
Field[] getFields()
//返回包含所有公共成员变量类对象的一个数组
Field getDeclaredField(String name)
//返回一个指定已声明成员变量类对象
Field[] getDeclaredFields()
//返回包含所有成员变量类对象的一个数组
使用成员变量对象
Object get(Object obj)
//返回该所表示的字段的值 Field ,指定的对象上。
void set(Object obj, Object value)
//将指定对象参数上的此 Field对象表示的字段设置为指定的新值。
public void setAccessible(boolean flag)
和构造方法相同若有私有成员变量需要取消访问检查
获取成员方法对象
Method getDeclaredMethod(String name, 类<?>... parameterTypes)
//返回一个指定声明的方法类对象
Method [] getDeclaredMethods()
//返回包含所有方法(但不包括继承的方法)的一个数组 。
Method getMethod(String name, 类<?>... parameterTypes)
//返回一个指定公共成员方法对象
Method[] getMethods()
//返回包含所有公共方法类对象的(包括那些由类或接口和那些从超类和超接口继承的声明) 一个数组
使用成员方法对象
Object invoke(Object obj, Object... args)
//在具有指定参数的 方法对象上调用此 方法对象表示的底层方法。
public void setAccessible(boolean flag)
代码演示
package com.ao;
public class Stu {
int name;
private int age;
public String gender;
public Stu(int name) {
this.name = name;
}
private Stu(String gender) {
this.gender = gender;
}
public Stu(int name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public Stu() {
}
@Override
public String toString() {
return "Stu{" +
"name=" + name +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
public void show(){
System.out.println("public show");
}
private void show1(int a){
System.out.println("private show1");
}
}
package com.ao;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Demo1 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException, ClassNotFoundException {
//获取class对象
Class c = Class.forName("com.ao.Stu");
//获取 所有的公有的构造方法
Constructor [] constructors = c.getConstructors();
for(Constructor con:constructors){
System.out.println(con.toString());
}
//获取公有的构造方法
Constructor constructor = c.getConstructor(int.class);
//用构造方法创键对象
Stu s =(Stu) constructor.newInstance(12);
//获取成员变量
Field field = c.getDeclaredField("age");
//私有成员变量需要取消编译期检查
field.setAccessible(true);
field.set(s,11);
System.out.println(s);
//获取成员方法
Method method = c.getMethod("show");
Method method1 = c.getDeclaredMethod("show1", int.class);
method.invoke(s);
//私有方法需要取消编译期查
method1.setAccessible(true);
method1.invoke(s,12);
}
}