Java反射

一、反射

1.反射:反射允许对封装类的字段,方法和构造函数的信息进行编程访问

二、获取class对象的三种方式

①class.forName("全类名");---->源代码阶段

②类名.class------>加载阶段

③对象.getClass();------>运行阶段

代码演示:

Student类:

package a10myreflect;

public class Student {
    private String name;
    private int age;

    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 + "}";
    }
}

测试类:

package a10myreflect;

public class MyReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.第一种方式
        //最为常用的
        Class clazz1 = Class.forName("a10myreflect.Student");
        //打印
        //System.out.println(clazz1);//class a10myreflect.Student

        //第二种方式
        //一般更多的是当做参数进行传递
        //例如:synchronized ()

        Class clazz2 = Student.class;
       // System.out.println(clazz1==clazz2);//true

        //第三种方式
        //当我们已经有了这个类的对象时才可以使用
        Student s=new Student();
        Class clazz3 = s.getClass();
        System.out.println(clazz1==clazz2);//true
        System.out.println(clazz2==clazz3);//true

    }
}

运行结果:

 

三、反射获取构造方法

代码演示:

Student1类:

package a10myreflect;

public class Student1 {
    private String name;
    private int age;

    public Student1() {
    }

    public Student1(String name){
        this.name=name;
    }
    protected Student1(int age){
        this.age=age;
    }
    private Student1(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 "Student1{name = " + name + ", age = " + age + "}";
    }
}

测试类:

package a10myreflect;

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("a10myreflect.Student1");
        //2.获取构造方法
     /*   Constructor[] cons = clazz.getConstructors();
        for (Constructor con : cons) {
            System.out.println(con);
        }
        */

     /*   Constructor[] cons2 = clazz.getDeclaredConstructors();
        for (Constructor con : cons2) {
            System.out.println(con);
        }
        */

     /*   Constructor con1 = clazz.getDeclaredConstructor();
        System.out.println(con1);

        Constructor con2 = clazz.getDeclaredConstructor(String.class);
        System.out.println(con2);

        Constructor con3 = clazz.getDeclaredConstructor(int.class);
        System.out.println(con3);
      */
        Constructor con4 = clazz.getDeclaredConstructor(String.class,int.class);
        //System.out.println(con4);
     /* int modifiers = con4.getModifiers();//获取权限修饰符,以整数形式体现
        System.out.println(modifiers);//2

        Parameter[] parameters = con4.getParameters();//获取全部参数
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
     */

        //临时取消权限的校验--->暴力反射
        con4.setAccessible(true);
        Student1 stu = (Student1) con4.newInstance("zhangsan", 23);//创建对象
        System.out.println(stu);
    }
}

运行结果:

 

四、反射获取成员变量

代码演示:

Student2类:

package a10myreflect;

public class Student2 {
    private String name;
    private int age;
    public String gender;

    public Student2() {
    }

    public Student2(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 "Student2{name = " + name + ", age = " + age + ", gender = " + gender + "}";
    }
}

 测试类:

package a10myreflect;

import java.lang.reflect.Field;

public class MyReflectDemo3 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //1.获取class字节码文件对象
        Class clazz = Class.forName("a10myreflect.Student2");
        //2.获取所有的成员变量
      /*  Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field);
        }
       */

        //获取单个的成员变量
        Field gender = clazz.getField("gender");
        System.out.println(gender);//public java.lang.String a10myreflect.Student2.gender
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);//private java.lang.String a10myreflect.Student2.name

        //获取权限修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);//2
        //获取成员变量名
        String n = name.getName();
        System.out.println(n);//name
        //获取成员变量数据类型
        Class<?> type = name.getType();
        System.out.println(type);//class java.lang.String
        //获取成员变量记录的值
        Student2 s=new Student2("zhangsan",23,"男");
        name.setAccessible(true);
        String  value = (String) name.get(s);
        System.out.println(value);//zhangsan
        //修改对象里面记录的值
        name.set(s,"lisi");
        System.out.println(s);//Student2{name = lisi, age = 23, gender = 男}

    }
}

运行结果:

 

五、反射获取成员方法

代码演示:

Student3类: 

package a10myreflect;

import java.io.IOException;

public class Student3 {
    private String name;
    private int age;

    public Student3() {
    }

    public Student3(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 void sleep(){
        System.out.println("睡觉");
    }
    private String eat(String something)throws IOException,NullPointerException,ClassCastException {
        System.out.println("在吃"+something);
        return "好吃";
    }
    public String toString() {
        return "Student3{name = " + name + ", age = " + age + "}";
    }
}

 测试类:

package a10myreflect;

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("a10myreflect.Student3");
        //2.获取里面所有的方法对象(包含父类中所有的公共方法)
      /*  Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
      */

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

        //获取指定的单一方法
        Method m = clazz.getDeclaredMethod("eat", String.class);
        System.out.println(m);//private void a10myreflect.Student3.eat(java.lang.String)
        //获取方法的修饰符
        int modifiers = m.getModifiers();
        System.out.println(modifiers);//2
        //获取方法的名字
        String name = m.getName();
        System.out.println(name);//eat
        //获取方法的形参
        Parameter[] parameters = m.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);//java.lang.String arg0
        }
        //获取方法的抛出异常
        Class<?>[] exceptionTypes = m.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        //方法运行
        Student3 s=new Student3();
        //参数1 s:表式方法的调用者
        //参数2:“火锅”:表示在调用方法的时候传递的实际参数
        m.setAccessible(true);
        String  result =(String) m.invoke(s, "火锅");//在吃火锅
        System.out.println(result);//好吃

    }
}

运行结果:

 

 五、反射的作用:

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

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

练习1:保存信息

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

 Student类:

package a11myreflect;

public 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;
    }

    /**
     * 获取
     * @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 char getGender() {
        return gender;
    }

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

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

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

    /**
     * 获取
     * @return hobby
     */
    public String getHobby() {
        return hobby;
    }

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

    public String toString() {
        return "Student{name = " + name + ", age = " + age + ", gender = " + gender + ", height = " + height + ", hobby = " + hobby + "}";
    }
}

Teacher类:

package a11myreflect;

public class Teacher {
    private String name;
    private double salary;

    public Teacher() {
    }

    public Teacher(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

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

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

    /**
     * 获取
     * @return salary
     */
    public double getSalary() {
        return salary;
    }

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

    public String toString() {
        return "Teacher{name = " + name + ", salary = " + salary + "}";
    }
}

测试类:

 

package a11myreflect;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;

public class MyReflectDemo {
    public static void main(String[] args) throws IllegalAccessException, IOException {
        Student s=new Student("小A",23,'女',167.5,"睡觉");
        Teacher t=new Teacher("小B",10000);
        saveObject(t);
    }
    public static void saveObject(Object obj) throws IllegalAccessException, IOException {
        //1.获取字节码文件的对象
        Class<?> clazz = obj.getClass();
        //创建IO流
        BufferedWriter bw=new BufferedWriter(new FileWriter("Test\\a.txt"));
        //2.获取所有的成员变量
        Field[] fileds = clazz.getDeclaredFields();
        for (Field field : fileds) {
            field.setAccessible(true);
            //获取成员变量的名字
            String name = field.getName();
            //获取成员变量的值
            Object value = field.get(obj);
            //写出数据
            bw.write(name+"="+value);
            bw.newLine();//换行
        }
        bw.close();
    }
}

 运行结果:

练习2:跟配置文件结合动态创建

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

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值