> 文章列表 > Java反射

Java反射

Java反射

反射

  • 反射
    • 获取class对象的三种方式
    • 利用反射获取构造方法
    • 利用反射获取成员变量
    • 利用反射获取成员方法
  • 综合练习

反射

  • 反射允许对封装类的字段,方法和构造函数的信息进行编程访问。
  • 作用:
    1、获取一个类里面所有的信息,获取到了之后,再执行其它的业务逻辑
    2、结合配置文件,动态的创建对象并调用方法

获取class对象的三种方式

  • 获取class对象的三种方式
    1、Class.forName(“全类名”);
    2、类名.class
    3、对象.getClass();
public class MyReflectDemo1 {public static void main(String[] args) throws ClassNotFoundException {//1、第一种方式//全类名:包名 + 类名//最为常用Class clazz1 = Class.forName("day0130.Student");//2、第二种方式//一般更多的是当中参数进行传递Class clazz2 = Student.class;//3、第三种方式//当我们已经有了这个类的对象时,才可以使用Student s = new Student();Class clazz3 = s.getClass();System.out.println(clazz1);//class day0130.StudentSystem.out.println(clazz1 == clazz2);//trueSystem.out.println(clazz2 == clazz3);//true}
}

利用反射获取构造方法

Java反射

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
public class MyReflectDemo2 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {//1、获取class字节码文件对象Class clazz = Class.forName("day0130.Student");//2、获取构造方法/*Constructor[] cons1 = clazz.getConstructors();for (Constructor con : cons1) {System.out.println(con);}System.out.println("-----------------");Constructor[] cons2 = clazz.getDeclaredConstructors();for (Constructor con : cons2) {System.out.println(con);}System.out.println("-----------------");Constructor con1 = clazz.getConstructor();System.out.println(con1);System.out.println("-----------------");Constructor con2 = clazz.getDeclaredConstructor(String.class);System.out.println(con2);System.out.println("-----------------");Constructor con3 = clazz.getDeclaredConstructor(int.class);System.out.println(con3);System.out.println("-----------------");*/Constructor con4 = clazz.getDeclaredConstructor(String.class,int.class);System.out.println(con4);int modifiers = con4.getModifiers();System.out.println(modifiers);Parameter[] parameters = con4.getParameters();for (Parameter parameter : parameters) {System.out.println(parameter);}//暴力反射:表示临时取消权限的校验con4.setAccessible(true);Student stu = (Student) con4.newInstance("zhangsan", 23);System.out.println(stu);}
}

利用反射获取成员变量

Java反射

import java.lang.reflect.Field;
public class MyReflectDemo3 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {//1、获取class字节码文件的对象Class clazz = Class.forName("day0130.Student");//2、获取所有的成员变量/*Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {System.out.println(field);}*///获取单个的成员变量Field gender = clazz.getField("gender");System.out.println(gender);//获取权限修饰符int modifiers = gender.getModifiers();System.out.println(modifiers);//1//获取成员变量的名字String name = gender.getName();System.out.println(name);//gender//获取成员变量的数据类型Class<?> type = gender.getType();System.out.println(type);//获取成员变量记录的值Student s = new Student("zhangsan",23,"男");Object value = gender.get(s);System.out.println(value);//修改对象里面记录的值gender.set(s,"女");System.out.println(s);}
}

利用反射获取成员方法

Java反射

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class MyReflectDemo4 {public static void main(String[] args) throws ClassNotFoundException,NoSuchMethodException,InvocationTargetException, IllegalAccessException {//1、获取class字节码文件对象Class clazz = Class.forName("day0130.Student");//2、获取里面所有的方法对象(包含父类中的所有公共方法)Method[] methods1 = clazz.getMethods();for (Method method : methods1) {System.out.println(method);}System.out.println("------------------------");//3、获取里面所有的方法对象(不能获取父类的,但可以获取本类中私有的方法)Method[] methods2 = clazz.getDeclaredMethods();for (Method method : methods2) {System.out.println(method);}System.out.println("------------------------");//获取指定的单一方法Method m = clazz.getDeclaredMethod("eat", String.class);System.out.println(m);//获取方法的修饰符int modifiers = m.getModifiers();System.out.println(modifiers);//2//获取方法的名字String name = m.getName();System.out.println(name);//获取方法的形参Parameter[] parameters = m.getParameters();for (Parameter parameter : parameters) {System.out.println(parameter);}//获取方法抛出的异常Class[] exceptionTypes = m.getExceptionTypes();for (Class exceptionType : exceptionTypes) {System.out.println(exceptionType);}//方法运行/*Method类中用于创建对象的方法Object invoke(Object obj, Object... args): 运行方法参数一:用obj对象调用该方法参数二:调用方法的传递的参数(如果没有就不写)返回值:方法的返回值(如果没有就不写)*/Student s = new Student();m.setAccessible(true);//参数一s:表示方法的调用者//参数二:“汉堡包”:表示在调用方法的时候传递的实际参数Object result = m.invoke(s, "汉堡包");//在吃汉堡包System.out.println(result);//ok}
}

JavaBean类特有的方法

public void sleep(){System.out.println("睡觉");}private String eat(String something)throws IOException,NullPointerException {System.out.println("在吃" + something);return "ok";}

综合练习

1、保存信息
对于任意一个对象,都可以把对象所有的字段名和值,保存到文件中去

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
public class Test {public static void main(String[] args) throws IOException, IllegalAccessException {Student s = new Student("小A",23,"女",167.5,"睡觉");Teacher t = new Teacher("老师A",10000);saveObject(s);}//把对象里面所有的成员变量名和值保存到本地文件中private static void saveObject(Object obj) throws IOException,IllegalAccessException {//1、获取字节码文件的对象Class clazz = obj.getClass();//2、创建IO流BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\\\Test2\\\\a.txt"));//3、获取所有的成员变量Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {field.setAccessible(true);//获取成员变量的名字String name = field.getName();//获取成员变量的值Object value = field.get(obj);//写出数据bw.write(name + "=" + value);bw.newLine();}bw.close();}
}

2、跟配置文件结合动态创建
反射可以跟配置文件结合的方式,动态的创建对象,并调用方法

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 Test2 {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {//1、读取配置文件中的信息Properties prop = new Properties();FileInputStream fis = new FileInputStream("D:\\\\Test\\\\untitled4\\\\src\\\\prop.properties");prop.load(fis);fis.close();System.out.println(prop);//2、获取全类名和方法名String classname = (String) prop.get("classname");String methodName = (String) prop.get("method");System.out.println(classname);System.out.println(methodName);//3、利用反射创建对象并运行方法Class clazz = Class.forName(classname);//获取构造方法Constructor con = clazz.getDeclaredConstructor();Object o = con.newInstance();System.out.println(o);//获取成员方法并运行Method method = clazz.getDeclaredMethod(methodName);method.setAccessible(true);method.invoke(o);}
}
  • 配置文件prop.properties信息
classname=day0130.Student
method=study
  • 学生类和教师类特有的方法
//学生类
public void study(){System.out.println("学生在学习!");}
//教师类
public void teach(){System.out.println("老师在教书");}

爱唱歌网