Java_反射

        反射允许对成员变量、成员方法和构造方法的信息进行编程访问。

        因为反射需要对class文件进行操作,下面先介绍获取class对象的三种方式

获取class对象的三种方式:

1.Class.forName("全类名")

2.类名.class

3.对象.getClass

代码演示:
public class ClassDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.Class.forName("全类名")
        //全类名:包名+类名
        //最为常用
        Class clazz1 = Class.forName("com.han.reflection.Student");

        //2.类名.class
        //一般更多是当作参数进行传递
        Class clazz2 = Student.class;

        //3.对象.getClass
        //当已经有了这个类的对象时,才可以使用
        Student s = new Student();
        Class clazz3 = s.getClass();

        System.out.println(clazz1 == clazz2);
        System.out.println(clazz3 == clazz2);

    }
}
运行结果:

反射获取

1.构造方法

代码演示:
测试类:
public class ClassDemo2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {

        Class clazz = Class.forName("com.han.reflection.Student");

        //获取所有public的构造方法
        Constructor[] cons1 = clazz.getConstructors();
        for (Constructor constructor : cons1) {
            System.out.println(constructor);
        }
        System.out.println("-----------------------------");

        //获取所有的构造方法
        Constructor[] cons2 = clazz.getDeclaredConstructors();
        for (Constructor constructor : cons2) {
            System.out.println(constructor);
        }
        System.out.println("-----------------------------");

        //获取单个public修饰的构造方法(参数中要写对应参数类型的字节码文件)
        Constructor con1 = clazz.getConstructor();
        System.out.println(con1);
        Constructor con2 = clazz.getConstructor(int.class);
        System.out.println(con2);
        System.out.println("-----------------------------");

        //获取单个任意修饰符修饰的构造方法(参数中要写对应参数类型的字节码文件)
        Constructor con3 = clazz.getDeclaredConstructor(String.class);
        System.out.println(con3);
        Constructor con4 = clazz.getDeclaredConstructor(String.class, int.class);
        System.out.println(con4);
        System.out.println("-----------------------------");

        //获取构造方法的权限修饰符
        int modifiers = con4.getModifiers();
        System.out.println(modifiers);
        System.out.println("-----------------------------");

        //利用获取的构造方法创建对象
        //创建有权限调用的
        Student stu1 = (Student) con2.newInstance(21);
        System.out.println(stu1);
        System.out.println("-----------------------------");
        //创建没有权限调用的
        //硬调用
        //暴力反射:临时取消权限检验
        con4.setAccessible(true);
        Student stu2 = (Student) con4.newInstance("han", 22);
        System.out.println(stu2);


    }
}
Student类:
public class Student {
    private String name;
    private int age;


    public Student() {
    }

    public Student(int age) {
        this.age = age;
    }

    protected Student(String name) {
        this.name = name;
    }

    private Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}
运行结果:

2.成员变量

代码演示:
测试类:
public class ReflcetionDemo1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {

        //获取字节码文件
        Class clazz = Class.forName("com.han.reflection.field.Student");

        //获取所有的成员变量
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("------------------------------");

        //获取单个成员变量
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);
        System.out.println("------------------------------");

        //获取权限修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);
        System.out.println("------------------------------");

        //获取成员变量名字
        String n = name.getName();
        System.out.println(n);
        System.out.println("------------------------------");

        //获取成员变量数据类型
        Class type = name.getType();
        System.out.println(type);
        System.out.println("------------------------------");

        //获取成员变量记录的值
        Student stu = new Student("han",21,"男");
        //暴力反射
        name.setAccessible(true);
        String value = (String) name.get(stu);
        System.out.println(value);

        //修改成员变量记录的值
        name.set(stu,"hanhan");
        System.out.println(stu);


    }
}
Student类:
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;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * 获取
     * @return gender
     */
    public String getGender() {
        return gender;
    }

    /**
     * 设置
     * @param gender
     */
    public void setGender(String gender) {
        this.gender = gender;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + ", gender = " + gender + "}";
    }
}
运行结果:

3.成员方法

代码演示:
测试类:
public class ReflectionDemo1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        //获取字节码文件对象
        Class clazz = Class.forName("com.han.reflection.method.Student");

        //获取所有的方法对象(包含父类中所有的公共方法)
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("------------------");

        //获取所有的方法对象(不能获取父类的,但是可以获取本类中私有的方法)
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("------------------");

        //获取指定的单一方法
        Method method = clazz.getDeclaredMethod("eat", String.class);
        System.out.println(method);
        System.out.println("------------------");

        //获取方法的修饰符
        int modifiers = method.getModifiers();
        System.out.println(modifiers);
        System.out.println("------------------");

        //获取方法的名字
        String name = method.getName();
        System.out.println(name);
        System.out.println("------------------");

        //获取方法的形参
        Parameter[] parameters = method.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
        System.out.println("------------------");

        //获取方法抛出的异常
        Class[] exceptionTypes = method.getExceptionTypes();
        for (Class exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }
        System.out.println("------------------");

        //运行方法
        //先创建对象
        Student s = new Student();
        method.setAccessible(true);
        method.invoke(s, "包子");


    }
}
Student类:
public class Student {
    private String name;
    private int age;

    public void sleep() {
        System.out.println("在睡觉");
    }

    private void eat(String something) throws IOException , ClassCastException {
        System.out.println("在吃" + something);
    }

    private void eat(String something, int n) {
        System.out.println("在吃" + something);
    }


}
运行结果:

单词含义:

get:获取set:设置
Constructor:构造方法Parameter:参数
Field:成员变量Modifiers:修饰符
Method:方法Declared:私有的

反射的作用:

        1.获取一个类里面所有的信息,获取到了之后,再执行其他的业务逻辑

        2.结合配置文件,动态的创建对象并调用方法

练习题:

练习一:

        定义一个方法,对于任何一个对象,都可以把对象所有的字段名和值,保存到文件中去

代码演示:
测试类:
public class Test1 {
    public static void main(String[] args) throws IOException, IllegalAccessException {

        //定义一个方法,对于任何一个对象,都可以把对象所有的字段名和值,保存到文件中去

        Student s = new Student("han",21,"男",175.0);
        Teacher t = new Teacher("zhang",36);

        saveObject(s);
        saveObject(t);

    }

    private static void saveObject(Object obj) throws IllegalAccessException, IOException {
        Class clazz = obj.getClass();

        BufferedWriter bw = new BufferedWriter(new FileWriter(
                "C:\\Users\\Han\\IdeaProjects\\myreflection\\src\\com\\han\\reflection\\test\\test1\\a.txt",true));
        Field[] fields = clazz.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();

    }


}
Student类:
public class Student {
    private String name;
    private int age;
    private String gender;
    private double height;


    public Student() {
    }

    public Student(String name, int age, String gender, double height) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.height = height;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * 获取
     * @return gender
     */
    public String getGender() {
        return gender;
    }

    /**
     * 设置
     * @param gender
     */
    public void setGender(String gender) {
        this.gender = gender;
    }

    /**
     * 获取
     * @return height
     */
    public double getHeight() {
        return height;
    }

    /**
     * 设置
     * @param height
     */
    public void setHeight(double height) {
        this.height = height;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + ", gender = " + gender + ", height = " + height + "}";
    }
}
Teacher类:
public class Teacher {

    private String name;
    private int age;


    public Teacher() {
    }

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Teacher{name = " + name + ", age = " + age + "}";
    }
}
运行结果:

练习二:

        通过将反射和配置文件结合,动态的创建对象,并调用方法

配置文件:

代码演示:
测试类:
public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {

        //读取配置文件信息
        Properties prop = new Properties();
        FileInputStream fis = new FileInputStream(
                "C:\\Users\\Han\\IdeaProjects\\myreflection\\src\\com\\han\\reflection\\test\\test2\\prop.properties");
        prop.load(fis);
        //{classname=com.han.reflection.test.test2.Student, methodname=study}
        String className = (String) prop.get("className");
        String methodName = (String) prop.get("methodName");


        //获取字节码文件
        Class clazz = Class.forName(className);

        //获取构造方法
        Constructor cons = clazz.getDeclaredConstructor();
        Object o = cons.newInstance();

        //调用方法
        Method method = clazz.getMethod(methodName);
        method.setAccessible(true);
        method.invoke(o);

    }
}
Student类:
public class Student {
    private String name;
    private int age;


    public void study() {
        System.out.println("学生在学习");
    }

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}
运行结果:

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值