反射
概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
双亲委派机制:
工作原理:
1)如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的
加载器去执行;
2)如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达项层的启
动类加载器;
3)如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子
加载器才会尝试自己去加载,这就是双亲委派机制。
反射的使用
Object ——> getClass();
任何数据类型(包括基本数据类型)都有一个“静态”的class属性
通过Class类的静态方法:forName(String className)(常用)
package Demo;
//反射之创建对象
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
//第一种
Student student = new Student();
Class<? extends Student> aClass = student.getClass();
//第二种
Class<Student> aClass1 = Student.class;
//第三种
Class<?> aClass2 = Class.forName("Demo.Student");
}
}
类的成员
-
成员变量 Field
-
构造方法 Constructor
-
成员方法 Method
反射之构造方法
A:获取所有构造方法
public Constructor<?>[] getConstructors() 获取所有的公共的构造方法不包含私有的
public Constructor<?>[] getDeclaredConstructors() 获取所有的构造方法 包括私有的
B:获取单个构造方法
public Constructor<T> getConstructor(Class<?>... parameterTypes) 获取单个的公共的构造方法 不包含私有的
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取单个的构造方法包含私有的
public class Student {
public Student() {
System.out.println("空参构造执行了");
}
public Student(String name) {
System.out.println("一个参数的构造执行了-" + name);
}
public Student(String name, int age) {
System.out.println("两个参数的构造执行了-" + name + "===" + age);
}
private Student(String name, int age, double sal) {
System.out.println("三个个参数的私有构造执行了-" + name + "===" + age + "====" + sal);
}
}
//反射之构造方法
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> aClass = Class.forName("Demo1.Student");
Constructor<?> constructor = aClass.getConstructor();
Student o = (Student) constructor.newInstance();
System.out.println(o);
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test2 {
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException, NoSuchMethodException {
Class<?> aClass = Class.forName("Demo1.Student");
Constructor<?> constructor1 = aClass.getConstructor(String.class);
Object wang = constructor1.newInstance("王三");
System.out.println(wang);
System.out.println("===========");
Constructor<?> constructor2 = aClass.getConstructor(String.class, int.class);
Object zhao = constructor2.newInstance("赵未", 23);
System.out.println(zhao);
System.out.println("==========");
Constructor<?> constructor3 = aClass.getDeclaredConstructor(String.class, int.class, double.class);
constructor3.setAccessible(true);
Object li = constructor3.newInstance("李然", 23, 6.5);
System.out.println(li);
}
}
反射之成员变量
A:获取所有成员变量
public Field[] getFields() 获取所有公共的成员变量包含从父类继承过来的
public Field[] getDeclaredFields() 获取所有的成员变量 包含私有的 也包含从父类继承过来的成员变量
B:获取单个成员变量
public Field getField(String name)
public Field getDeclaredField(String name)
public class Teacher {
public String name;
public int age;
private double sex;
}
package Demo2;
//反射之成员变量
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class Test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
Class<?> aClass = Class.forName("Demo2.Teacher");
//获取所有的成员变量
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//获取公共的成员变量
System.out.println("=======");
Field[] fields = aClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("==========");
//获取指定的成员变量
Field name = aClass.getField("name");
System.out.println(name);
System.out.println("==========");
Field sex = aClass.getDeclaredField("sex");
System.out.println(sex);
}
}
package Demo2;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class Test2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
//更改成员变量值
Class<?> aClass = Class.forName("Demo2.Teacher");
Teacher teacher = (Teacher) aClass.getConstructor().newInstance();//通过构造方法new一个对象
//给公共成员变量赋值
Field name = aClass.getField("name");
name.set(teacher,"张三");
String names = (String) name.get(teacher);
System.out.println(names);
Field age = aClass.getField("age");
age.setInt(teacher,20);
int anInt = age.getInt(teacher);
System.out.println(anInt);
//给私有成员变量赋值
Field sex = aClass.getDeclaredField("sex");
//将私有改为公共
sex.setAccessible(true);
sex.setDouble(teacher,3.22);
double aDouble = sex.getDouble(teacher);
System.out.println(aDouble);
}
}
发射之成员方法
A:获取所有成员方法
public Method[] getMethods() //获取所有的公共的成员方法不包含私有的 包含从父类继承过来的过来的公共方法
public Method[] getDeclaredMethods()//获取自己的所有成员方法 包含私有的
B:获取单个成员方法
//参数1: 方法名称 参数2:方法行参的class 对象
public Method getMethod(String name,Class<?>... parameterTypes) //获取单个的方法 不包含私有的
public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取单个方法包括私有的
package Demo3;
public class Dog {
public void show() {
System.out.println("我是小白");
}
public int hehe(String name) {
System.out.println("呵呵" + name);
return 100;
}
public double haha(String name, int age) {
System.out.println("哈哈" + name + "===" + age);
return 3.25;
}
private void test(String name) {
System.out.println("私有的方法调用了" + name);
}
}
package Demo3;
//反射之成员方法
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws NoSuchMethodException {
Class<Dog> dogClass = Dog.class;
//获取所有的公共的成员方法对象,包括父类的。
Method[] methods = dogClass.getMethods();
for (Method method : methods) {
System.out.println(methods);
}
System.out.println("===========");
//获取成员方法对象包括私有
Method[] methods1 = dogClass.getDeclaredMethods();
for (Method method : methods1) {
System.out.println(methods1);
}
System.out.println("===========");
Method show = dogClass.getMethod("show");
Method test = dogClass.getMethod("test", String.class);
}
}
package Demo3;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test2 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Class<Dog> dogClass = Dog.class;
// Class<?> aClass = Class.forName("Demo3.Dog");
Dog dog = dogClass.newInstance();
//传入方法名
Method show = dogClass.getMethod("show");
show.invoke(dog);
System.out.println("==========");
Method haha = dogClass.getMethod("haha", String.class, int.class);
Double ha = (Double) haha.invoke(dog, "小黑", 2);
System.out.println(ha);
System.out.println("==========");
//
Method test = dogClass.getDeclaredMethod("test", String.class);
test.setAccessible(true);
String haha1 = (String) test.invoke(dog, "haha");
System.out.println(haha1);
}
}