乐趣区

关于java:Java中反射的概念意义用法适合新手阅读

引言

Java 中 JRE、JDK、javac.exe、java.exe 的区别及 Java 运行机制

反射的概念

  • Java 语言的 反射机制

    1. 在程序运行时,对于任意一个类,都可能 晓得 这个类的所有属性和办法;
    2. 在程序运行时,对于任意一个对象,都可能 调用 它的任意属性和办法;
    3. 动静 获取信息以及 动静 调用对象办法;(前面解释动静的意思)
  • 益处
      个别创立类对象,并调用其中属性和办法,无奈间接调到 private 润饰的成员。而利用反射调用它类中的属性和办法时,忽视权限修饰符。

反射的意义(动静的解释)

  • 假如此时 用户 须要三个类办法:学生类、老师类、工人类,都是规范的 JavaBean 类
// 学生类
public class Student {
    private String name;
    private int age;

    public Student() {}

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

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
// 老师类
public class Teacher {
    private String name;
    private int age;

    public Teacher() {}

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

    public void teach(){System.out.println("老师在上课");
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
// 工人类
public class Worker {
    private String name;
    private int age;

    public Worker() {}

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

    public void work(){System.out.println("工人在工作");
    }

    @Override
    public String toString() {
        return "Worker{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

一、不必反射

  • 作为程序员,咱们先写好了学生类,而后写 main 办法类,将两个类打包给用户应用。
// 应用学生类的主办法类
public class TestReflect {public static void main(String[] args) {Student stu = new Student();
        stu.study();// 学生在学习}
}
  • 之后,咱们又增加了老师办法,要交给用户应用。用户须要接管 新写的老师办法 新写的 main 办法类
// 应用学生、老师类的主办法类
public class TestReflect {public static void main(String[] args) {Student stu = new Student();
        stu.study();// 学生在学习

        Teacher tea = new Teacher();
        tea.teach();// 老师在上课}
}
  • 再之后,咱们又增加了工人办法,要交给用户应用。用户须要接管 新写的工人办法 新写的 main 办法类
// 应用学生、老师、工人类的主办法类
public class TestReflect {public static void main(String[] args) {Student stu = new Student();
        stu.study();// 学生在学习

        Teacher tea = new Teacher();
        tea.teach();// 老师在上课

        Worker wor = new Worker();
        wor.work();// 工人在工作}
}
  • 总结:这里能够看出,每次减少性能,都须要重写 main 办法,再交给用户应用。代码中,明确阐明了要创立的对象是 Student、Teacher、Worker…,写死了,不具备灵活性。

二、应用反射

  • 应用反射,咱们减少一个 properties 配置文件,将创建对象的类名写在此文件中。主办法读到哪个对象,就用反射创立谁的字节码文件对象。读到什么,就创立什么,因而它是 动静 的。
  • 文件构造展现:
  • properties 配置文件:

    className=myreflect1.Worker
    methodName=work
    
  • main 办法:(此处波及反射的用法,可先看懂,学完用法后再来了解一遍)
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class ReflectDemo1 {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // 获取零碎类加载器,加载 prop.properties 文件
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("myreflect1\\prop.properties");
        // 创立 Properties 汇合
        Properties prop = new Properties();
        // 将文件中的数据读取到汇合当中
        prop.load(is);
        is.close();

        //-------- 上面的代码就是利用反射创建对象并调用办法 ---------------------

        // 获取字节码文件对象
        Class clazz = Class.forName(prop.getProperty("className"));
        // 获取结构器对象
        Constructor constructor = clazz.getConstructor();
        // 利用结构器对象创立一个对象
        Object o = constructor.newInstance();
        // 获取办法对象
        Method method = clazz.getMethod(prop.getProperty("methodName"));
        // 运行办法
        method.invoke(o); // 后果:工人在工作
    }
}
  • 总结:应用反射后,无论用户须要应用哪个对象,咱们只须要把批改好的配置文件发给用户应用。而用户手上的 main 办法代码无需批改,具备较高的灵活性。

三、反射机制的再次了解:

  1. 利用反射能够 忽视 修饰符获取类外面所有的属性和办法。(在用法中重点解说)
  2. 先获取配置文件中的信息,动静 获取信息并创建对象、调用办法。

反射的用法

网上有很多介绍了,这里给出一个写的挺好的:
Java 反射机制及 API 应用

退出移动版