关于反射
getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。

顺便记一下:
@Override这个标签
可以当作注释用,没什么特别的
可以告诉读你代码的人,这是对它父类方法的重写,其实很多代码规范没有为什么,规范就是规范,代码的可读性还是很重要的。
编译器可以给你验证
@Override下面的方法名称是否是你父类中所有的,如果没有就会报错。
比如当你想要在子类中重写父类的一个方法,但是你把名字打错了,当你写了@Override编译器会提示你,你写的这个方法父类中没有;但是如果你没有写@Override编译器就会觉得这个是你子类中写的新的方法,并不会报错,到时候你debug还是很麻烦的一件事。
摘自【https://blog.csdn.net/upc1607020107/article/details/81274398】感觉这个博主说的就很好了,就直接摘抄过来了
反射的其他两种
String str = "test";System.out.println(str.getClass());//静态方法Class class_name = Class.forName("java.lang.String");
getDeclaredField():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
Class类提供了以下几个方法来获取Method
Method getMethod(name, Class...):获取某个public的Method(包括父类)Method getDeclaredMethod(name, Class...):获取当前类的某个Method(不包括父类)Method[] getMethods():获取所有public的Method(包括父类)Method[] getDeclaredMethods():获取当前类的所有Method(不包括父类)
需要执行的话,就需要将方法名传入invoke()方法。有以下两种方式
System.out.println(substring.invoke(test));//调用带参数的方法,需要传参System.out.println(substring.invoke(test,"admin"));
执行命令的方法
Class.forName("java.lang.Runtime").getMethod("exec", String.class).invoke(Class.forName("java.lang.Runtime").getMethod("getRuntime").invoke(Class.forName("java.lang.Runtime")),"calc");
关于Final 修饰符,它可以用来修饰类,方法,变量
- 修饰类:当一个类使用final修饰时,表明这个类不能被继承。

- 修饰方法,表明这个方法被锁定,任何继承这个类之后都不能修改这个方法的含义。
- 修饰变量,这个使用的是最多的,也是了解final修饰符的主要原因之一,主要记住一点就是使用final修饰的变量,再初始化之后就不能被修改。
Class.forName(className) 相当于Class.forName(className, true, currentLoader
第⼆个参数表示是否初始化,在forName 的时候,构造函数并不会执⾏,而是执⾏类初始化。他会执行static{}静态块里面的内容
package com.test;import java.io.IOException;public class web {public static void main(String[] args) throws Exception {Class.forName("com.test.Calc");}}class Calc{static {try {Runtime.getRuntime().exec("calc");} catch (IOException e) {e.printStackTrace();}}}
反射原理
反射就是对于任意一个类,可以知道它的所有属性和方法,对于任意一个对象都能调用它的任意一个方法,在运行状态中,动态调用方法的功能获取对象的三种方式
- Class.forName()
Class aClass = Class.forName("com.reflecttest.Person");System.out.println(aClass);
- 类名.class
Class personClass = Person.class;System.out.println(personClass);
- 对象.getClass()
Person person = new Person();Class aClass1 = person.getClass();System.out.println(aClass1);
获取对象的功能的13种常用方法
package com.reflecttest;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ReflectDemo1 {public static void main(String[] args) throws Exception {/** 反射就是对于任意一个类,可以知道它的所有属性和方法,对于任意一个对象都能调用它的任意一个方法* 在运行状态中,动态调用方法的功能*获取对象的三种方法* 1. Class.forName()* 2. 类名.class* 3. getClass()* */Class aClass = Class.forName("com.reflecttest.Person");System.out.println(aClass);System.out.println("===========================");Class personClass = Person.class;System.out.println(personClass);System.out.println("===========================");Person person = new Person();Class aClass1 = person.getClass();System.out.println(aClass1);/** 1. 获取对象的功能* 1.1 获取成员变量* *///获取所有的public变量Field[] fields = personClass.getFields();for (Field field : fields) {System.out.println(field);}//获取指定的public变量Field field = personClass.getField("name");System.out.println(field);//获取所有成员变量(包括private & protected)Field[] declaredFields = personClass.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println(declaredField);}//获取指定的私有成员变量Field age = personClass.getDeclaredField("age");System.out.println(age);System.out.println("============================================");/*1.2 获取构造方法*/Constructor[] constructors = personClass.getConstructors();for (Constructor constructor : constructors) {System.out.println(constructor);}//获取指定方法(有参无参)Constructor constructor = personClass.getConstructor(String.class, int.class, String.class);System.out.println(constructor);System.out.println("==========================");Constructor[] declaredConstructors = personClass.getDeclaredConstructors();for (Constructor declaredConstructor : declaredConstructors) {System.out.println(declaredConstructor);}//1.3 获取成员方法// 获取所有公有成员方法Method[] methods = personClass.getMethods();for (Method method : methods) {System.out.println(method);}//获取指定成员方法Method method = personClass.getMethod("love");System.out.println(method);//操作method.invoke(person);System.out.println("========================================");//获取所有成员方法Method[] declaredMethods = personClass.getDeclaredMethods();for (Method declaredMethod : declaredMethods) {System.out.println(declaredMethod);}Method love = personClass.getDeclaredMethod("love");love.invoke(person);}}
访问并修改调用私有属性的时候,出于安全性检查,会拒绝调用,这时可以使用一行代码来忽略这个私有属性的访问权限安全性检测。
反射练习案例
在不修改代码的情况下,创建任意类和执行任意方法
这里主要是涉及到一个配置文件的使用,这里如果是在maven中,参考https://www.yuque.com/m0re/demosec/sr2n6h#PkCid
package com.reflecttest;import java.io.InputStream;import java.lang.reflect.Method;import java.util.Properties;public class ReflectDemo2 {public static void main(String[] args) throws Exception {//创建Properties对象Properties properties = new Properties();//加载配置文件,转换为一个集合(使用到加载器)// 获取class目录下的配置文件ClassLoader classLoader = ReflectDemo2.class.getClassLoader();//获取同文件的加载器InputStream is = classLoader.getResourceAsStream("pro.properties");//转换为流properties.load(is);//载入//获取配置文件中定义的数据String className = properties.getProperty("ClassName");String methodName = properties.getProperty("MethodName");//加载该类进内存Class aClass = Class.forName(className);//创建对象Object obj = aClass.newInstance();//获取方法对象Method method = aClass.getMethod(methodName);method.invoke(obj);}}
