Java反射机制的详细讲解

目录

1.反射机制是什么?

2.反射机制能干什么?

3.反射相关的类

​编辑

4.Class类(反射机制的起源 )

5.反射机制相关的API

1.(重要)常用获得类相关的方法

2.常用获得类中属性相关的方法(以下方法返回值为Field相关

3.(了解)获得类中注解相关的方法

4.(重要)获得类中构造器相关的方法(以下方法返回值为Constructor相关)

​编辑 5.(重要)获得类中方法相关的方法(以下方法返回值为Method相关)

6.反射示例

1.获得Class对象的三种方式

 2.反射的使用

1.产生对象

方法一:调用类的无参构造,且该构造方法必须是public权限!!

 方法二:通过Constructer类来调用构造方法产生对象

2.通过反射操作类中的方法

7、反射优点和缺点


1.反射机制是什么?

Java反射是指在程序运行期间,可以动态的获取到任意一个类的相关信息,并且调用任意对象的属性或方法,这种动态获取类的信息的方式和动态调用对象方法的功能称之为Java对象的反射机制

Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java文件.class也被JVM解析为一个对象,这个对象就是 java.lang.Class .这样当程序在运行时,每个java文件就最终变成了Class类对象的一个实例。我们通过Java的反射机制应用到这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类成为一个动态的类

2.反射机制能干什么?

通过Java语言中的反射机制可以操作字节码文件,还可以操作代码片段(class文件)

Java反射机制的相关类都在Java.long.reflect.*;包下

3.反射相关的类

Java反射机制的详细讲解_第1张图片

4.Class(反射机制的起源 )

Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java文件.class也被JVM解析为 一个对象,这个对象就是 java.lang.Class .这样当程序在运行时,每个java文件就最终变成了Class类对象的一个实 例。我们通过Java的反射机制应用到这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类成 为一个动态的类 .

5.反射机制相关的API

1.(重要)常用获得类相关的方法

Java反射机制的详细讲解_第2张图片

2.常用获得类中属性相关的方法(以下方法返回值为Field相关

  • getField(String name) :获得某个公有的属性对象
  • getFields() :获得所有公有的属性对象
  • getDeclaredField(String name) :获得某个属性对象
  • getDeclaredFields() :获得所有属性对象

3.(了解)获得类中注解相关的方法

Java反射机制的详细讲解_第3张图片

4.(重要)获得类中构造器相关的方法(以下方法返回值为Constructor相关

Java反射机制的详细讲解_第4张图片 5.(重要)获得类中方法相关的方法(以下方法返回值为Method相关

  • getMethod(String name, Class... parameterTypes) :获得该类某个公有的方法
  • getMethods() :获得该类所有公有的方法
  • getDeclaredMethod(String name, Class... parameterTypes) :获得该类某个方法
  • getDeclaredMethods() :获得该类所有方法

6.反射示例

1.获得Class对象的三种方式

在反射之前,我们需要做的第一步就是先拿到当前需要反射的类的Class对象,然后通过Class对象的核心方法,达到反射的目的,即:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息。
第一种 ,使用 Class.forName(" 类的全路径名 "); 静态方法。
前提:已明确类的全路径名。
第二种 ,使用  类名称.class 方法。
说明:仅适合在编译前就已经明确要操作的 Class
第三种 ,使用类任意对象的 getClass() 方法
package com.example.reflect.model;

public class Student {
    // 共有属性name
    private String name;
    // 私有属性age
    private Integer age;

    // 不带参数的构造方法
    public Student() {
    }

    // 带参数的构造方法
    private Student(String name, Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("Student(String,name)");
    }

    private void eat(){
        System.out.println("i am eat");
    }
    public void sleep(){
        System.out.println("i am pig");
    }
    private void function(String str) {
        System.out.println(str);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
class TeatReflect {
    public static void main(String[] args) {
        /**
         * 1.通过getClass获取Class对象
         */
        Student student = new Student();
        Class c = student.getClass();
        /**
         * 2.直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
         * 这说明任何一个类都有一个隐含的静态成员变量 class
         */
        Class c2 = Student.class;
        /**
         * 3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
         * 但可能抛出 ClassNotFoundException 异常
         */
        Class c3 = null;
        try {
            c3 = Class.forName("com.example.reflect.model.Student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //一个类在 JVM 中只会有一个 Class 实例,即我们对上面获取的
        //c1,c2,c3进行 equals 比较,发现都是true
        System.out.println(c.equals(c2));
        System.out.println(c3.equals(c2));
        System.out.println(c3.equals(c));
    }
}

 2.反射的使用

1.产生对象

方法一:调用类的无参构造,且该构造方法必须是public权限!!

 // 产生对象
    public static void reflectNewInstance() {
        try {
            Class classStudent = Class.forName("com.example.reflect.model.Student");
            // 调用的是无参构造,且必须是公有的
            Object objectStudent = classStudent.newInstance();
            Student student = (Student) objectStudent;
            System.out.println("获得学生对象:"+student);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

如果使私有的无参构造那么就会报错了,就像下面这样:

Java反射机制的详细讲解_第5张图片

此时我们通过无参构造去获取对象:

Java反射机制的详细讲解_第6张图片

 方法二:通过Constructer类来调用构造方法产生对象

Constructer类就是Java中利用反射操作构造方法的类

  • getConstructor(参数):获取该类的所有public 权限的构造方法
  • getDeclareConstructor:获取该类的所有权限的构造方法,包括私有权限
    // 产生对象
    public static void reflectNewInstance2() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 获取Class对象
        Class classStudent = Student.class;
        // 获得所有的构造方法
        Constructor[] constructors = (Constructor[]) classStudent.getDeclaredConstructors();
        System.out.println(Arrays.toString(constructors));
        // 获取私有的有参构造
        Constructor constructor = classStudent.getDeclaredConstructor(String.class,Integer.class);
        // 破坏封装性·
        constructor.setAccessible(true);
        // 通过私有构造方法创建对象
        Student student = constructor.newInstance("锦鲤",18);
        System.out.println(student);
    }

反射可以获得所有的不论公有私有的方法和属性,他会破坏封装性,只在当前JVM进程中可见

2.通过反射操作类中的方法

    // 操作方法
    public static void reflectByMethod() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 获取Class对象
        Class classStudent = Student.class;
        Method[] methods = classStudent.getDeclaredMethods();
        System.out.println(Arrays.toString(methods));
        // 通过反射来调用普通方法和静态方法
        // 调用普通方法首先要产生对象
        Student student = classStudent.newInstance();
        // 通过反射拿到fun方法的反射方法
        Method methodFun = classStudent.getMethod("fun", String.class);
        // 通过Method反射对象调用fun方法, 传入调用该方法的对象以及需要传入的参数
        methodFun.invoke(student, "锦鲤");
        // 调用静态方法
        Method methodTest = classStudent.getMethod("test");
        methodTest.invoke(null);
    }

7、反射优点和缺点

优点:
  • 1. 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法
  • 2. 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力
  • 3. 反射已经运用在了很多流行框架如:StrutsHibernateSpring 等等。
缺点:
  • 1. 使用反射会有效率问题。会导致程序效率降低。具体参考这里:http://www.imooc.com/article/293679
  • 2. 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 

反射的讲解就到这里啦!

下篇博客见~ 

Java反射机制的详细讲解_第7张图片

你可能感兴趣的:(springboot,Java语法,Java,EE,python,开发语言)