Java-反射的三种获取方式,反射的变量、方法、构造方法和作用

简介:反射(Reflection指的是允许以编程方式访问已加载类的成分(成员变量、方法、构造器等)。

一、获取反射的三种方式

        1. 反射的第一步都是先得到加载后的类,然后才可以去那类的其他成分。

        2. 获取Class类的对象的三种方式

方式一: Class c1 = Class.forName (“ 全类名 ”);
方式二: Class c2 = 类名 .class
方式三: Class c3 = 对象 . getClass ();

二、反射的构造方法

        在这里,获取Class对象的构造器作用依然是初始化一个对象返回,接下来是代码展示,并且相关代码进行了详细注解,包括获取Class对象的三种方式、获取Class对象的构造函数的相关方法以及使用Class对象的构造函数。

        首先是用做测试的Cat类,这里使用Cat类的Class对象做测试。

package com.itheima_reflect;

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

    public Cat() {
    }

    public Cat(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 "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

        这是主函数,包括了详细的代码

package com.itheima_reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class TestConstructor {
    public static void main(String[] args) throws Exception {
        /*
            以下代码演示创建Class对象的三种方法
        */
        // 获取的Class的方法一
        Class<Cat> catClass = Cat.class;
        // 获取的Class的方法二
        Class<Cat> name = (Class<Cat>) Class.forName("MyHomeTest\\src\\com\\itheima_reflect\\Cat.java");
        // 获取的Class的方法三
        Cat cat = new Cat();
        Class<? extends Cat> getClass = cat.getClass();

        /*
        * 以下代码是使用反射技术获取构造器对象并使用
        */
        // 返回所有构造器对象的数组(只能拿public的)
        // 在这里需要注意,如果Class对象的其中一个构造函数是用private关键字修饰,那么这个构造函数是遍历不到的
        Constructor<?>[] constructors = catClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor.getName() + "---->" + constructor.getParameterCount());
        }

        // 返回所有构造器对象的数组
        // 在这里需要注意,即使Class对象的其中一个构造函数是用private关键字修饰,也能遍历到
        Constructor<?>[] declaredConstructors = catClass.getDeclaredConstructors();
        for (Constructor<?> constructor : declaredConstructors) {
            // 输出Class对象中构造函数的名称和参数数量
            System.out.println(constructor.getName() + "---->" + constructor.getParameterCount());
        }

        // 返回单个构造器对象(只能拿public的)
        Constructor<Cat> constructor = catClass.getConstructor();//如果不填写参数,调用Class对象的无参构造函数
        System.out.println(constructor.getName() + "---->" + constructor.getParameterCount());

        /**
         * 以下代码展示的是使用Class对象的构造函数创建对象
         */
        // 通过newInstance()方法创建一个Cat对象
        Cat newCat = catClass.newInstance();
        // 暴力破解,如果当前catClass这个构造函数在Cat类中是私有的,那么不执行暴力破解会报错
        // public void  setAccessible(boolean flag)
        // catClass.setAccessible(boolean flag)
    }
}

三、反射的变量

        Class类中用于获取成员变量的方法,在代码中详细解释。这是主函数,包括了详细的代码(还是继续使用了Cat类)

package com.itheima_reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class TestConstructor {
    public static void main(String[] args) throws Exception {
        /*
            以下代码演示创建Class对象的三种方法
        */
        // 获取的Class的方法一
        Class<Cat> catClass = Cat.class;
        // 获取的Class的方法二
        Class<Cat> name = (Class<Cat>) Class.forName("MyHomeTest\\src\\com\\itheima_reflect\\Cat.java");
        // 获取的Class的方法三
        Cat cat = new Cat();
        Class<? extends Cat> getClass = cat.getClass();

        /**
         * 以下代码,展示的是如何获取Cat类的Class对象的变成员变量
         */
        // 返回所有成员变量对象的数组(只能拿public的)。在这里,因为Cat类中的成员变量都是使用private修饰的,所以数组为空
        Field[] fields = catClass.getFields();
        // 返回所有成员变量对象的数组,存在就能拿到
        Field[] declaredFields = catClass.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println(field.getName());
        }
        // 返回单个成员变量对象(只能拿public的),在这里,因为Cat类中的成员变量都是使用private修饰的,所以变量为空
        Field field = catClass.getField("name");
        // 返回单个成员变量对象,存在就能拿到
        Field declaredField = catClass.getDeclaredField("name");
    }
}

四、反射的方法

        Class类中用于获取成员方法的方法,在代码中详细解释。这是主函数,包括了详细的代码(还是继续使用了Cat类)

package com.itheima_reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestConstructor {
    public static void main(String[] args) throws Exception {
        /*
            以下代码演示创建Class对象的三种方法
        */
        // 获取的Class的方法一
        Class<Cat> catClass = Cat.class;
        // 获取的Class的方法二
        Class<Cat> name = (Class<Cat>) Class.forName("MyHomeTest\\src\\com\\itheima_reflect\\Cat.java");
        // 获取的Class的方法三
        Cat cat = new Cat();
        Class<? extends Cat> getClass = cat.getClass();

        /**
         * 以下代码,展示的是如何获取Cat类的Class对象的方法
         */
        // 返回所有成员方法对象的数组(只能拿public的)
        Method[] methods = catClass.getMethods();
        for (Method method : methods) {
            System.out.println(method.getName() + "----." + method.getParameterCount() + "---->" + method.getParameterTypes());
        }
        // 返回所有成员方法对象的数组,存在就能拿到
        Method[] declaredMethods = catClass.getDeclaredMethods();
        for (Method method : declaredMethods) {
            System.out.println(method.getName() + "----." + method.getParameterCount() + "---->" + method.getParameterTypes());
        }
        // 返回单个成员方法对象(只能拿public的)
        Method method = catClass.getMethod("getName"); // 参数为要获取的方法名和以及要获取的方法参数
        // 返回单个成员方法对象,存在就能拿到
        Method getName = catClass.getDeclaredMethod("getName"); // 参数为要获取的方法名和以及要获取的方法参数
/*        // 返回所有成员变量对象的数组(只能拿public的)。在这里,因为Cat类中的成员变量都是使用private修饰的,所以数组为空
        Field[] fields = catClass.getFields();
        // 返回所有成员变量对象的数组,存在就能拿到
        Field[] declaredFields = catClass.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println(field.getName());
        }
        // 返回单个成员变量对象(只能拿public的),在这里,因为Cat类中的成员变量都是使用private修饰的,所以变量为空
        Field field = catClass.getField("name");
        // 返回单个成员变量对象,存在就能拿到
        Field declaredField = catClass.getDeclaredField("name");*/
    }
}

五、反射的作用

        在这里通过一个小案例来展示反射的功能和作用。本案例是实现一个获取运行中对象的字段数据,并且将字段名和字段值打印到指定的文件中去。

        首先是创建两个类:Student、Teacher  

package com.itheima_reflect;

public class Student {
    private String name;
    private int age;
    private char sex;
    private double height;
    private String hobby;

    public Student() {
    }

    public Student(String name, int age, char sex, double height, String hobby) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        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 getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    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 +
                ", sex=" + sex +
                ", height=" + height +
                ", hobby='" + hobby + '\'' +
                '}';
    }
}
package com.itheima_reflect;

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

        接下来创建一个反射框架类,通过反射获取运行中对象的Class对象,通过获取的Class对象来获取相应的字段信息。 具体代码如下

package com.itheima_reflect;

import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;

public class ObjectFrame {
    // 功能:保存任意对象的字段和相应数据到文件中去
    public static void saveObject(Object object) throws Exception {
        // 创建一个打印流,用以向文件中打印数据
        PrintStream printStream = new PrintStream(new FileOutputStream("D:\\LenovoSoftstore\\Install\\IDEA\\IDEAProject\\MyHomeTest\\src\\user.txt", true));
        // 获取object对象的Class对象
        Class aClass = object.getClass();
        String simpleName = aClass.getSimpleName();
        printStream.println("----------" + simpleName + "-------------");
        // 通过这个Class对象(aClass)获取全部字段
        Field[] fields = aClass.getDeclaredFields();
        // 遍历每一个成员变量
        for (Field field : fields) {
            // 禁止检查访问控制
            field.setAccessible(true);
            // 通过field获取字段名称
            String name = field.getName();
            // 通过field获取字段值
            String value = field.get(object) + "";
            printStream.println(name + " = " + value);
        }
        printStream.close();
    }
}

        最后是测试类,对上述功能代码进行测试。代码如下。

package com.itheima_reflect;

public class FrameTest {
    public static void main(String[] args) {
        Student student = new Student("王大宁", 18, '男', 188, "乒乓球");
        Teacher teacher = new Teacher("柳岩", 170);

        try {
            ObjectFrame.saveObject(student);
            ObjectFrame.saveObject(teacher);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

        以上就是一个通过一个小案例来展示反射的功能和作用。代码经过小猿亲测可跑。

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
获取Student类的所有构造方法、成员方法和成员变量,可以使用Java反射机制。下面是示例代码: ```java import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Main { public static void main(String[] args) { Class<Student> studentClass = Student.class; // 获取所有构造方法 Constructor<?>[] constructors = studentClass.getConstructors(); System.out.println("Constructors:"); for (Constructor<?> constructor : constructors) { System.out.println(constructor); } // 获取所有成员方法 Method[] methods = studentClass.getMethods(); System.out.println("\nMethods:"); for (Method method : methods) { System.out.println(method); } // 获取所有成员变量 Field[] fields = studentClass.getDeclaredFields(); System.out.println("\nFields:"); for (Field field : fields) { System.out.println(field); } } } class Student { private String name; private int age; private int classId; private String sex; private int score; public Student(String name, int age, int classId, String sex, int score) { this.name = name; this.age = age; this.classId = classId; this.sex = sex; this.score = score; } public String getName() { return name; } public int getAge() { return age; } public int getClassId() { return classId; } public String getSex() { return sex; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } } ``` 输出结果: ``` Constructors: public Student(java.lang.String,int,int,java.lang.String,int) Methods: public int Student.getAge() public void Student.setScore(int) public int Student.getClassId() public int Student.getScore() public java.lang.String Student.getSex() public java.lang.String Student.getName() public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException ... Fields: private java.lang.String Student.name private int Student.age private int Student.classId private java.lang.String Student.sex private int Student.score ``` 注意:这里的示例代码使用了`Student`类来表示学生,你可以根据实际情况进行调整。`getConstructors()`方法获取的是所有公共构造方法,`getMethods()`方法获取的是所有公共成员方法,`getDeclaredFields()`方法获取的是所有成员变量(包括私有成员变量)。如果需要获取非公共的构造方法方法变量,可以使用相应的方法,如`getDeclaredConstructors()`、`getDeclaredMethods()`和`getDeclaredFields()`。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值