Java笔记_22
- 一、反射
- 1.1、反射的概述
- 1.2、获取class对象的三种方式
- 1.3、反射获取构造方法
- 1.4、反射获取成员变量
- 1.5、反射获取成员方法
- 1.6、综合练习
- 1.6.1、保存信息
- 1.6.2、跟配置文件结合动态创建
一、反射
1.1、反射的概述
什么是反射?
反射允许对成员变量,成员方法和构造方法的信息进行编程访问
1.2、获取class对象的三种方式
- Class.forName(“全类名”);
全类名:包名+类名
- 类名.class
- 对象.getclass()
package reflect.Dome1;
public class Dome {
public static void main(String[] args) throws ClassNotFoundException {
//方式一
Class aClass = Class.forName("reflect.Dome1.student");
System.out.println(aClass);
//方式二
Class aClass1 = student.class;
System.out.println(aClass1);//与方式一的结果相同
student s = new student();
Class aClass2 = s.getClass();
System.out.println(aClass2);//三个方式结果相同
}
}
package reflect.Dome1;
public 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 String toString() {
return "student{name = " + name + ", age = " + age + "}";
}
}
1.3、反射获取构造方法
Class类中用于获取构造方法的方法
方法名称 | 说明 |
---|---|
Constructor<?>[ ] getConstructors() | 返回所有公共构造方法对象的数组 |
Constructor<?>[ ] getDeclaredConstructors() | 返回所有构造方法对象的数组 |
Constructor<T> getConstructor(Class<?>… parameterTypes) | 返回单个公共构造方法对象 |
Constructor<T> getDeclaredConstructor(Class<?>… parameterTypes) | 返回单个构造方法对象 |
Constructor类中用于创建对象的方法
方法名称 | 说明 |
---|---|
T newlnstance(Object… initargs) | 根据指定的构造方法创建对象 |
setAccessible(boolean flag) | 设置为true,表示取消访问权限 |
package reflect.Dome2;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class dome {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class class1 = Class.forName("reflect.Dome2.student");
Constructor[] constructors = class1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
Constructor con = class1.getDeclaredConstructor(String.class,int.class);
System.out.println(con);
Constructor[] declaredConstructors = class1.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
//如果是私有构造方法,则不能直接使用,只能看到
//通过添加setAccessible方法,暴力取消临时权限校验。就可以使用
con.setAccessible(true);
student stu = (student) con.newInstance("张三", 21);
System.out.println(stu);
}
}
package reflect.Dome2;
public class student {
private String name;
private int age;
public student() {
}
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;
}
public String toString() {
return "student{name = " + name + ", age = " + age + "}";
}
}
1.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 reflect.Dome3;
import java.lang.reflect.Field;
public class dome {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Class clazz = Class.forName("reflect.Dome3.Student");
//获取到公共成员变量
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}
//查找该成员变量
Field gender = clazz.getField("gender");
System.out.println(gender);
//获取所有的成员变量
Field[] declaredField = clazz.getDeclaredFields();
for (Field field : declaredField) {
System.out.println(field);
}
//获取私有变量
Field name = clazz.getDeclaredField("name");
System.out.println(name);
//获取权限修饰符
int modifiers = name.getModifiers();
System.out.println(modifiers);
//获取成员变量的名称
String name1 = name.getName();
System.out.println(name1);
//获取成员变量的类型
Class<?> type = name.getType();
System.out.println(type);
//创建一个对象
Student s = new Student("张三",23,"男");
name.setAccessible(true);
Object o = name.get(s);
System.out.println(o);
//修改s里面name的值
name.set(s,"小王");
System.out.println(s);
}
}
package reflect.Dome3;
public 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;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + ", gender = " + gender + "}";
}
}
1.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 reflect.Dome4;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class dome {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class aClass = Class.forName("reflect.Dome4.student");
//包括父类的方法
Method[] methods = aClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("===================================");
//不包括父类的方法
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("===================================");
//返回单个公共成员方法变量
Method getAge = aClass.getMethod("setAge", int.class);
System.out.println(getAge);
System.out.println("===================================");
//返回单个成员方法对象
Method eat = aClass.getDeclaredMethod("eat", String.class);
System.out.println(eat);
//返回方法的名称
System.out.println("===================================");
String name = eat.getName();
System.out.println(name);
System.out.println("===================================");
Class<?> declaringClass = eat.getDeclaringClass();
System.out.println(declaringClass);
System.out.println("===================================");
//返回方法里面的参数
Parameter[] parameters = eat.getParameters();
for (Parameter parameter : parameters) {
System.out.println(parameter);
}
System.out.println("===================================");
//返回方法抛出的异常
Class<?>[] exceptionTypes = eat.getExceptionTypes();
for (Class<?> exceptionType : exceptionTypes) {
System.out.println(exceptionType);
}
//利用反射运行方法
student s = new student("xiaowang",23,'男');
eat.setAccessible(true);
//没有返回值就不需要写
//eat.invoke(s, "烧烤");
//果如有返回值就需要写
String o = (String) eat.invoke(s, "烧烤");
System.out.println(o);
}
}
package reflect.Dome4;
import java.io.IOException;
public class student {
private String name;
private int age;
public char gender;
public student() {
}
public student(String name, int age, char 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 char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
private String eat(String str) throws IOException,RuntimeException,ArithmeticException {
System.out.println(getName()+"正在吃"+str);
return "奥利给";
}
public String toString() {
return "student{name = " + name + ", age = " + age + ", gender = " + gender + "}";
}
}
1.6、综合练习
反射的作用:
- 获取一个类里面所有的信息,获取到了之后,再执行其他的业务逻辑
- 结合配置文件,动态的创建对象并调用方法
1.6.1、保存信息
package reflect.Dome5;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
public class dome {
public static void main(String[] args) throws IllegalAccessException, IOException {
student s = new student("小明",18,181.0,"玩");
teacher t = new teacher("王老师",30);
printClass(t);
}
public static void printClass(Object obj) throws IllegalAccessException, IOException {
Class aClass = obj.getClass();
//创建IO流
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\Java\\IDEA\\代码文件\\Three\\a.txt"));
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
//进行修饰符忽略
declaredField.setAccessible(true);
//获取到该变量的名字
String name = declaredField.getName();
//获取到该变量的值
Object value = declaredField.get(obj);
//写出数据
bw.write(name+"="+value);
bw.newLine();
System.out.println(name+"="+value);
}
bw.flush();
bw.close();
}
}
package reflect.Dome5;
public class student {
private String name;
private int age;
private double height;
private String hobby;
public student() {
}
public student(String name, int age, double height, String hobby) {
this.name = name;
this.age = age;
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;
}urn height
*/
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;
}
public String toString() {
return "student{name = " + name + ", age = " + age + ", height = " + height + ", hobby = " + hobby + "}";
}
}
package reflect.Dome5;
public class teacher {
private String name;
private int age;
public teacher() {
}
public teacher(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 String toString() {
return "teacher{name = " + name + ", age = " + age + "}";
}
}
1.6.2、跟配置文件结合动态创建
package reflect.Dome6;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class dome {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//读取配置文件中的信息
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("prop.properies");
//读取的文件
prop.load(fis);
fis.close();
System.out.println(prop);
//获取全类名和方法名
Object classname = prop.get("classname");
Object method = prop.get("method");
System.out.println(classname);
System.out.println(method);
//利用反射创建对象并运行方法
Class<?> aClass = Class.forName((String) classname);
//获取构造方法
Constructor con = aClass.getDeclaredConstructor();
Object o = con.newInstance();
System.out.println(o);
//获取成员方法并运行
Method declaredMethod = aClass.getDeclaredMethod((String) method);
declaredMethod.setAccessible(true);
declaredMethod.invoke(o);
}
}
package reflect.Dome6;
public class student {
private String name;
private int age;
private char gender;
public student() {
}
public student(String name, int age, char gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public void study(){
System.out.println("正在学习");
}
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 String toString() {
return "student{name = " + name + ", age = " + age + ", gender = " + gender + "}";
}
}
classname=reflect.Dome6.student
method=study