目录
1.什么是反射
反射允许对成员变量,成员方法和构造方法的信息进行编程访问
2. 获取class对象的三种方式
- Class.forName("全类名");
- 类名.class
- 对象.getclass();
例如:
package yj.com.easthome2.day0910;
/**
* Class.forName("全类名");
* 类名.class
* 对象.getclass();
*/
public class MyReflectDemo01 {
public static void main(String[] args) throws ClassNotFoundException {
// Class.forName("全类名");
//最常用
Class<?> aClass = Class.forName("yj.com.easthome2.day0910.Student");
System.out.println(aClass);//class yj.com.easthome2.day0910.Student
//类名.class
//更多作为参数传递
Class<Student> studentClass = Student.class;
System.out.println(studentClass);//class yj.com.easthome2.day0910.Student
//对象.getclass();
//我们已经有了这个类的对象时使用
Student student = new Student();
Class<? extends Student> aClass1 = student.getClass();
System.out.println(aClass1);//class yj.com.easthome2.day0910.Student
}
}
class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
3.利用反射获取构造方法
Class类中用于获取构造方法的方法
- Constructor<?>[] getConstructors(): 返回所有公共构造方法对象的数组
- Constructor<?>[] getDeclaredConstructors(): 返回所有构造方法对象的数组
- Constructor<T>getConstructor(Class<?>... parameterTypes): 返回单个公共构造方法对象
- Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes):返回单个构造方法对象
Constructor类中用于创建对象的方法
- T newInstance(Object...initargs): 根据指定的构造方法创建对象
- setAccessible(boolean flag): 设置为true,表示取消访问检查
例如:
package yj.com.easthome2.day0910.MyReflectDemo02;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
/**
* Class类中用于获取构造方法的方法
* Constructor<?>[]getConstructors(): 返回所有公共构造方法对象的数组
* Constructor<?>[] getDeclaredConstructors(): 返回所有构造方法对象的数组
* Constructor<T>getConstructor(Class<?>... parameterTypes): 返回单个公共构造方法对象
* Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes):返回单个构造方法对象
*
* Constructor类中用于创建对象的方法
* T newInstance(Object...initargs): 根据指定的构造方法创建对象
* setAccessible(boolean flag): 设置为true,表示取消访问检查
*/
public class MyReflectDemo02 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1.获取class字节码文件对象
Class<?> aClass = Class.forName("yj.com.easthome2.day0910.MyReflectDemo02.Student");
//2.获取所有公共构造方法们
Constructor<?>[] cons = aClass.getConstructors();
for (Constructor<?> constructor : cons) {
System.out.println(constructor);
// 结果:
//public yj.com.easthome2.day0910.MyReflectDemo02.Student(java.lang.String)
// public yj.com.easthome2.day0910.MyReflectDemo02.Student()
}
System.out.println("----------------");
//3.获取所有构造方法
Constructor<?>[] dcs = aClass.getDeclaredConstructors();
for (Constructor<?> dc : dcs) {
System.out.println(dc);
// 结果:
//private yj.com.easthome2.day0910.MyReflectDemo02.Student(java.lang.String,int)
// protected yj.com.easthome2.day0910.MyReflectDemo02.Student(int)
// public yj.com.easthome2.day0910.MyReflectDemo02.Student(java.lang.String)
// public yj.com.easthome2.day0910.MyReflectDemo02.Student()
}
System.out.println("-----------------");
//4.获取单个公共构造方法
Constructor<?> con = aClass.getDeclaredConstructor();
System.out.println(con);
//结果
// public yj.com.easthome2.day0910.MyReflectDemo02.Student()
Constructor<?> con2 = aClass.getDeclaredConstructor(String.class);
System.out.println(con2);
//结果
//public yj.com.easthome2.day0910.MyReflectDemo02.Student(java.lang.String)
Constructor<?> con3 = aClass.getDeclaredConstructor(int.class);
System.out.println(con3);
// protected yj.com.easthome2.day0910.MyReflectDemo02.Student(int)
Constructor<?> con4 = aClass.getDeclaredConstructor(String.class, int.class);
System.out.println(con4);
//private yj.com.easthome2.day0910.MyReflectDemo02.Student(java.lang.String,int)
System.out.println("------------");
int modifiers = con4.getModifiers();// 返回此类或接口的Java语言修饰符,以整数编码。
System.out.println(modifiers);//2
Parameter[] parameters = con4.getParameters();//获取这个构造方法所有的参数
for (Parameter parameter : parameters) {
System.out.println(parameter);
// java.lang.String arg0
// int arg
}
System.out.println("------------------------");
//暴力反射
con4.setAccessible(true);//临时取消权限的校验
Object nn = con4.newInstance("念念", 10);
System.out.println(nn);//Student{name='念念', age=10}
}
}
class Student {
private String name;
private int age;
public Student() {
}
public Student(String name) {
this.name = name;
}
protected Student(int age) {
this.age = age;
}
private Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
4.利用反射获取成员变量
Class类中用于获取成员变量的方法
- Field[] getFields():返回所有公共成员变量对象的数组
- Field[] getDeclaredFields():返回所有成员变量对象的数组
- Field getField(String name):返回单个公共成员变量对象
- Field getDeclaredField(String name):返回单个成员变量对象
Field类中用于创建对象的方法
- void set(Object obj, Object value): 赋值
- Object get(Object obj) 获取值。
例如:
package yj.com.easthome2.day0910.MyReflectDemo03;
import java.lang.reflect.Field;
/**
* Class类中用于获取成员变量的方法
* Field[] getFields():返回所有公共成员变量对象的数组
* Field[] getDeclaredFields():返回所有成员变量对象的数组
* Field getField(String name):返回单个公共成员变量对象
* Field getDeclaredField(String name):返回单个成员变量对象
*
* Field类中用于创建对象的方法
* void set(Object obj, Object value): 赋值
* Object get(Object obj) 获取值。
*/
public class MyReflectDemo03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
//1.获取class字节码文件对象
Class<?> aClass = Class.forName("yj.com.easthome2.day0910.MyReflectDemo03.Student");
//2.获取成员变量
Field[] fields = aClass.getFields();
for (Field field : fields) {
System.out.println(field);
//public java.lang.String yj.com.easthome2.day0910.MyReflectDemo03.Student.gender
}
System.out.println("----------------");
//获取所有成员变量,包括私有
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
// private java.lang.String yj.com.easthome2.day0910.MyReflectDemo03.Student.name
// private int yj.com.easthome2.day0910.MyReflectDemo03.Student.age
// public java.lang.String yj.com.easthome2.day0910.MyReflectDemo03.Student.gender
}
System.out.println("--------------");
//获取单个成员变量
Field field = aClass.getField("gender");
System.out.println(field);
// public java.lang.String yj.com.easthome2.day0910.MyReflectDemo03.Student.gender
//获取单个成员变量(私有)
Field name = aClass.getDeclaredField("name");
System.out.println(name);
//private java.lang.String yj.com.easthome2.day0910.MyReflectDemo03.Student.name
System.out.println("------------------");
//获取权限修饰符
int modifiers = name.getModifiers();
System.out.println(modifiers);//2
String name1 = name.getName();//获取成员变量名
System.out.println(name1);//name
Class<?> type = name.getType();//获取数据类型
System.out.println(type);//class java.lang.String
//获取成员变量记录的值
Student student = new Student("nn", 10, "男");
name.setAccessible(true);
Object o = name.get(student);
System.out.println(o);//nn
//修改对象里面记录的值
name.set(student, "bb");
System.out.println(student);
// Student{name='bb', age=10, gender='男'}
}
}
class Student {
private String name;
private int age;
public String gender;
public Student() {
}
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
5.利用反射获取成员方法
Class类中用于获取成员方法的方法
- Method[] getMethods(): 返回所有公共成员方法对象的数组,包括继承的
- Method[] getDeclaredMethods(): 返回所有成员方法对象的数组,不包括继承的
- Method getMethod(String name, Class<?>... parameterTypes): 返回单个公共成员方法对象
- Method getDeclaredMethod(String name, Class<?>... parameterTypes): 返回单个成员方法对象
Method类中用于创建对象的方法
- Object invoke(Object obj,Object... args): 运行方法
- 参数一:用obj对象调用该方法
- 参数二:调用方法的传递的参数(如果没有就不写)
- 返回值:方法的返回值(如果没有就不写)
例如:
package yj.com.easthome2.day0910.MyReflectDemo04;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
/**
* Class类中用于获取成员方法的方法
* Method[] getMethods(): 返回所有公共成员方法对象的数组,包括继承的
* Method[] getDeclaredMethods(): 返回所有成员方法对象的数组,不包括继承的
* Method getMethod(String name, Class<?>... parameterTypes): 返回单个公共成员方法对象
* Method getDeclaredMethod(String name, Class<?>... parameterTypes): 返回单个成员方法对象
*
* Method类中用于创建对象的方法
* Object invoke(Object obj,Object... args): 运行方法
* 参数一:用obj对象调用该方法
* 参数二:调用方法的传递的参数(如果没有就不写)
* 返回值:方法的返回值(如果没有就不写)
*/
public class MyReflectDemo04 {
public static void main(String[] args) throws Exception {
//1.获取class字节码文件对象
Class<?> aClass = Class.forName("yj.com.easthome2.day0910.MyReflectDemo04.Student");
// Method[] getMethods(): 返回所有公共成员方法对象的数组,包括继承的
Method[] methods = aClass.getMethods();
for (Method method : methods) {
System.out.println(method);
//public java.lang.String yj.com.easthome2.day0910.MyReflectDemo04.Student.toString()
// public java.lang.String yj.com.easthome2.day0910.MyReflectDemo04.Student.getName()
// public void yj.com.easthome2.day0910.MyReflectDemo04.Student.setName(java.lang.String)
// public void yj.com.easthome2.day0910.MyReflectDemo04.Student.sleep()
// public int yj.com.easthome2.day0910.MyReflectDemo04.Student.getAge()
// public void yj.com.easthome2.day0910.MyReflectDemo04.Student.setAge(int)
// public final void java.lang.Object.wait() throws java.lang.InterruptedException
// public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
// public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
// public boolean java.lang.Object.equals(java.lang.Object)
// public native int java.lang.Object.hashCode()
// public final native java.lang.Class java.lang.Object.getClass()
// public final native void java.lang.Object.notify()
// public final native void java.lang.Object.notifyAll()
}
System.out.println("------------------------");
//Method[] getDeclaredMethods(): 返回所有成员方法对象的数组,不包括继承的
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
//public java.lang.String yj.com.easthome2.day0910.MyReflectDemo04.Student.toString()
// public java.lang.String yj.com.easthome2.day0910.MyReflectDemo04.Student.getName()
// public void yj.com.easthome2.day0910.MyReflectDemo04.Student.setName(java.lang.String)
// public void yj.com.easthome2.day0910.MyReflectDemo04.Student.sleep()
// public int yj.com.easthome2.day0910.MyReflectDemo04.Student.getAge()
// public void yj.com.easthome2.day0910.MyReflectDemo04.Student.setAge(int)
// private void yj.com.easthome2.day0910.MyReflectDemo04.Student.eat(java.lang.String)
}
System.out.println("----------------------");
//Method getMethod(String name, Class<?>... parameterTypes): 返回单个公共成员方法对象
Method m = aClass.getMethod("sleep", null);
System.out.println(m);
//public void yj.com.easthome2.day0910.MyReflectDemo04.Student.sleep()
System.out.println("-----------------------------");
// Method getDeclaredMethod(String name, Class<?>... parameterTypes): 返回单个成员方法对象
Method method = aClass.getDeclaredMethod("eat", String.class);
System.out.println(method);
//private void yj.com.easthome2.day0910.MyReflectDemo04.Student.eat(java.lang.String)
System.out.println("---------------------");
//获取方法的修饰符
int modifiers = method.getModifiers();
System.out.println(modifiers);//2
//获取方法的名字
String name = method.getName();
System.out.println(name);//eat
//获取方法的形参
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
System.out.println(parameter);
//java.lang.String arg0
}
System.out.println("-------------");
//获取方法的抛出异常
Class<?>[] exceptionTypes = method.getExceptionTypes();
for (Class<?> exceptionType : exceptionTypes) {
System.out.println(exceptionType);
//class java.io.IOException
// class java.lang.NoSuchFieldException
}
System.out.println("-----------------------------------");
//获取方法的返回值
Student student = new Student();
//参数一:student表示方法的调用者
//参数二:"红烧肉"表示在调用方法的时候传递的实际参数
method.setAccessible(true);
Object o = method.invoke(student, "红烧肉");//再吃红烧肉
System.out.println(o);//好吃!
}
}
class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void sleep() {
System.out.println("睡觉");
}
private String eat(String food) throws IOException, NoSuchFieldException {
System.out.println("再吃" + food);
return "好吃!";
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
6.反射的作用
- 获取一个类里面所有的信息,获取到了之后,再执行其他的业务逻辑
- 结合配置文件,动态的创建对象并调用方法
例如:
package yj.com.easthome2.day0910.MyReflectDemo05;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
public class MyReflectDemo05 {
public static void main(String[] args) throws Exception {
Student s = new Student("nn", 10, '女', 162, "睡觉");
Teacher t = new Teacher("bb", 2000);
save(s);
}
public static void save(Object obj) throws IllegalAccessException, IOException {
//1.获取字节码文件的对象
Class<?> aClass = obj.getClass();
//创建io流
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\easthome\\ideaProjects\\javaSE\\java01\\src\\yj\\com\\easthome2\\day0910\\MyReflectDemo05\\aa.txt"));
//2.获取所有成员变量
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
//获取成员变量的名字
String name = field.getName();
//获取成员变量的值
Object o = field.get(obj);
// 写出数据
bw.write(name + "=" + o);
bw.newLine();
}
bw.close();
}
}
class Student {
private String name;
private int age;
private char gender;
private double height;
private String hobby;
public Student() {
}
public Student(String name, int age, char gender, double height, String hobby) {
this.name = name;
this.age = age;
this.gender = gender;
this.height = height;
this.hobby = hobby;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", gender=" + gender +
", height=" + height +
", hobby='" + hobby + '\'' +
'}';
}
}
class Teacher {
private String name;
private double salary;
public Teacher() {
}
public Teacher(String name, double salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", salary=" + salary +
'}';
}
}