反射
概念:java反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的方法和属性。
类加载器:
1.Bootstrap ClassLoader :根类加载器
2.Extension ClassLoader :扩展类加载器
3.System ClassLoader :系统类加载器(自己定义的类)
步骤:
一.要想使用反射,首先要获取该类对应的字节码文件对象
获取class文件对象的三种方式
1.通过Object类中的getClass()方法;
2.通过静态属性class. 例:Class c = Student.class;
3.[常用]通过Class类中的静态方法forName();
Class.forName(className:该类的全类名(带包的类))
二.剖析一个类
一个类的构成:构造方法(Constructor).成员变量(Field).成员方法(Method).
1.Constructor
(1)获取字节码文件对象
(2)获取构造方法对象
A:获取所有构造方法
public Constructor<?>[] getConstructors() 获取所有的构造方法对象数组 不包含私有的
public Constructor<?>[] getDeclaredConstructors() 获取所有的构造方法对象,包括私有的
B:获取单个构造方法
public Constructor<T> getConstructor(Class<?>... parameterTypes)获取指定的公有的构造方法
public Constructor<T>getDeclaredConstructor(Class<?>...parameterTypes:可变参数:数据类型.class)获取指定的公有私有的构造方法
取消语法检查:setAccessible(true)
(3)创建该类的对象
newInstance(Objecct...initarges)
2.Field
(1)获取字节码文件对象
(2)获取字段对象
A:获取所有成员变量
public Field[] getFields() 获取所有的字段 不包含私有字段 (包括父类公有)
public Field[] getDeclaredFields() 获取所有字段 包含私有字段 (无父类)
B:获取单个成员变量
public Field getField(String name) 获取单个的公有字段
public Field getDeclaredField(String name) 获取单个的公有字段或私有字段
(3)给字段赋值
set(Object obj , Object value)
对象 值
3.Method
(1)获取字节码文件对象
(2)获取成员方法对象
A:获取所有成员方法
public Method[] getMethods() 获取所有的共有的方法对象 包括父类的公共方法
public Method[] getDeclaredMethods() 获取所有的方法对象 包括私有的
B:获取单个成员方法
public Method getMethod(String name,Class<?>...parameterTypes) 获取指定的方法对象
public Method getDeclaredMethod(String name,Class<?>...parameterTypes) 获取私有的方法对象
(3)执行方法
invoke(Object obj , Object ... args);
对象 方法所要的实参
需求:通过反射的方法用文件实现方法的调用
代码:
public class Student {
public void show(){
System.out.println("这是学生类中的SHOW方法!");
}
public void method(){
System.out.println("这是学生类中的METHOD方法!");
}
}
public class Teacher {
public void show(){
System.out.println("这是老师类中的SHOW方法!");
}
public void method(){
System.out.println("这是老师类中的METHOD方法!");
}
}
public static void main(String[] args) throws IOException, Exception {
Properties p = new Properties();
p.load(new FileInputStream("a.txt"));
String name = p.getProperty("name");
String method = p.getProperty("method");
//获该类的字节码文件对象
Class cla=Class.forName(name);
//获取该成员方法,使用保险的方法
Method m = cla.getDeclaredMethod(method);
//执行该方法
m.invoke(cla.newInstance());
}
文件:
name=reflect.demo.Teacher
method=method
结果:
这是老师类中的METHOD方法!
需求:通过反射写一个通用的设置某个对象的某个属性为指定的值
代码:
public class Student {
private String name;
private int age;
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
public class MyTools {
public static void set(Student s, String string, String string2) throws Exception {
// 获取字节码文件对象
Class c = s.getClass();
Field f = c.getDeclaredField(string);
f.setAccessible(true);
f.set(s, string2);
}
}
public static void main(String[] args) throws Exception {
Student s = new Student();
MyTools.set(s,"name","张三");
System.out.println(s);
}
结果:
Student [name=张三, age=0]