引言
Java中JRE、JDK、javac.exe、java.exe的区别及Java运行机制
反射的概念
Java语言的 反射机制
- 在程序运行时,对于任意一个类,都可能晓得这个类的所有属性和办法;
- 在程序运行时,对于任意一个对象,都可能调用它的任意属性和办法;
- 动静获取信息以及动静调用对象办法;(前面解释动静的意思)
- 益处
个别创立类对象,并调用其中属性和办法,无奈间接调到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.WorkermethodName=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办法代码无需批改,具备较高的灵活性。
三、反射机制的再次了解:
- 利用反射能够忽视修饰符获取类外面所有的属性和办法。(在用法中重点解说)
- 先获取配置文件中的信息,动静获取信息并创建对象、调用办法。
反射的用法
网上有很多介绍了,这里给出一个写的挺好的:
Java反射机制及API应用