反射
反射
反射概念
JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制
本片产考博客: https://zhuoqianmingyue.blog.csdn.net/article/details/85090982
反射作用
反射原理
JAVA语言编译之后会生成一个.class文件,反射就是通过字节码文件找到某一个类、类中的方法以及属性等。
反射的实现主要借助以下四个类:
- Class:类的对象
- Constructor:类的构造方法
- Field:类中的属性对象
- Method:类中的方法对象
反射的使用
获取class对象的方式
package com.xwtech.test.反射; /** * 获取class对象的四种方式 * @author Liyongzhe * @date 2020/12/14_10:02 */ public class ClassCreatingMode { /** * @param args * @throws ClassNotFoundException */ public static void main(String[] args) throws ClassNotFoundException { //通过实例对象获取getClass方法 ClassCreatingMode model = new ClassCreatingMode(); Class<? extends ClassCreatingMode> class1 = model.getClass(); System.out.println("实例对象getClass:"+class1); //通过类名.class方法 Class<ClassCreatingMode> class2 = ClassCreatingMode.class; System.out.println("类名.class:"+class2); //通过Class对象的forName()静态方法获取 Class<?> class3 = Class.forName("com.xwtech.test.反射.ClassCreatingMode"); System.out.println("Class对象的forName()静态方法获取:"+class3); } }
打印结果
实例对象getClass:class com.xwtech.test.反射.ClassCreatingMode 类名.class:class com.xwtech.test.反射.ClassCreatingMode Class对象的forName()静态方法获取:class com.xwtech.test.反射.ClassCreatingMode
获取构造方法
package com.xwtech.test.反射.person; /** * @author Liyongzhe * @date 2020/12/14_10:17 */ public class Person { private String name; private Integer age; protected char sex; String address; public double salary; /** * 受保护的性别 构造方法 * @param sex */ protected Person(char sex) { this.sex = sex; System.out.println("protected Person(char sex)"); } /** * 私有的 年龄 构造方法 * @param age */ private Person(Integer age) { this.age = age; System.out.println("private Person(Integer age)"); } /** * 默认的 姓名和年龄 * @param name * @param age */ Person(String name,Integer age) { this.name = name; this.age = age; System.out.println("Person(String name,Integer age)"); } /** * 共有的 姓名 构造方法 * @param name */ public Person(String name) { this.name = name; System.out.println("public Person(String name)"); } /** * 无参数构造方法 */ public Person() { this.name = "default"; System.out.println("public Person()"); } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.xwtech.test.反射.person; import java.lang.reflect.Constructor; import java.lang.reflect.Parameter; /** * 获取构造方法 * @author Liyongzhe * @date 2020/12/14_10:21 */ public class ConstructTest { /** * 获取所有的公众方法 * @throws ClassNotFoundException */ public void findAllPublicConstruct()throws ClassNotFoundException{ Class<?> personClass = Class.forName("com.xwtech.test.反射.person.Person"); //获取所有的公共方法 Constructor<?>[] constructors = personClass.getConstructors(); //获取所有的构造方法 public private protected 默认修饰的构造方法 showConstructorsInfo(constructors); } /** * 获取所有的构造方法 * @throws ClassNotFoundException */ public void findAllConstructors() throws ClassNotFoundException{ Class<?> personClass = Class.forName("com.xwtech.test.反射.person.Person"); Constructor<?>[] constructors = personClass.getDeclaredConstructors(); showConstructorsInfo(constructors); } /** * 获取public 修饰的构造函数 * @throws ClassNotFoundException * @throws NoSuchMethodException * @throws SecurityException */ public void findPublicConstruct() throws ClassNotFoundException, NoSuchMethodException, SecurityException{ Class<?> personClass = Class.forName("com.xwtech.test.反射.person.Person"); Constructor<?> constructor = personClass.getConstructor(); showConstructor(constructor); } /** * 获取public 修饰的带有阐述的构造函数 * @throws ClassNotFoundException * @throws NoSuchMethodException */ public void findPublicConstructWithParam() throws ClassNotFoundException, NoSuchMethodException { Class<?> personClass = Class.forName("com.xwtech.test.反射.person.Person"); Constructor<?> constructor = personClass.getConstructor(String.class); showConstructor(constructor); } public void findConstructWithParam() throws ClassNotFoundException, NoSuchMethodException { Class<?> personClass = Class.forName("com.xwtech.test.反射.person.Person"); Constructor<?> protectConstructor = personClass.getDeclaredConstructor(char.class); showConstructor(protectConstructor); System.out.println("================================================="); Constructor<?> privateConstructor = personClass.getDeclaredConstructor(Integer.class); showConstructor(privateConstructor); System.out.println("================================================="); Constructor<?> constructor = personClass.getDeclaredConstructor(String.class, Integer.class); showConstructor(constructor); System.out.println("================================================="); Constructor<?> publicConstructor = personClass.getDeclaredConstructor(String.class); showConstructor(publicConstructor); System.out.println("================================================="); } private void showConstructorsInfo(Constructor<?>[] constructors) { for (Constructor<?> constructor : constructors) { showConstructor(constructor); System.out.println("================================================="); } } private void showConstructor(Constructor constructor) { System.out.println("constructor:"+constructor); String name = constructor.getName(); System.out.println("构造函数的名字:"+name); int parameterCount = constructor.getParameterCount(); System.out.println("构造函数的数量:"+parameterCount); Parameter[] parameters = constructor.getParameters(); for (Parameter parameter : parameters) { String parameterName = parameter.getName(); String typeName = parameter.getType().getName(); System.out.println("参数名称:"+parameterName+"类型是:"+typeName); } } public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException{ ConstructTest constructTest = new ConstructTest(); // constructTest.findAllPublicConstruct(); // constructTest.findAllConstructors(); // constructTest.findPublicConstruct(); // constructTest.findPublicConstructWithParam(); constructTest.findConstructWithParam(); } }
打印结果
- 公共构造方法 constructor:public com.xwtech.test.反射.person.Person() 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:0 ================================================= constructor:public com.xwtech.test.反射.person.Person(java.lang.String) 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:1 参数名称:arg0类型是:java.lang.String ================================================= - 所有构方法 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:0 ================================================= constructor:public com.xwtech.test.反射.person.Person(java.lang.String) 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:1 参数名称:arg0类型是:java.lang.String ================================================= constructor:com.xwtech.test.反射.person.Person(java.lang.String,java.lang.Integer) 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:2 参数名称:arg0类型是:java.lang.String 参数名称:arg1类型是:java.lang.Integer ================================================= constructor:private com.xwtech.test.反射.person.Person(java.lang.Integer) 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:1 参数名称:arg0类型是:java.lang.Integer ================================================= constructor:protected com.xwtech.test.反射.person.Person(char) 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:1 参数名称:arg0类型是:char ================================================= - 获取指定参数和不指参数的构造方法 + 获取不指定阐述的构造方法 constructor:public com.xwtech.test.反射.person.Person() 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:0 + 获取指定阐述的构造方法 ================================================= constructor:public com.xwtech.test.反射.person.Person(java.lang.String) 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:1 参数名称:arg0类型是:java.lang.String - 获取指定参数的私有构造方法 constructor:protected com.xwtech.test.反射.person.Person(char) 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:1 参数名称:arg0类型是:char ================================================= constructor:private com.xwtech.test.反射.person.Person(java.lang.Integer) 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:1 参数名称:arg0类型是:java.lang.Integer ================================================= constructor:com.xwtech.test.反射.person.Person(java.lang.String,java.lang.Integer) 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:2 参数名称:arg0类型是:java.lang.String 参数名称:arg1类型是:java.lang.Integer ================================================= constructor:public com.xwtech.test.反射.person.Person(java.lang.String) 构造函数的名字:com.xwtech.test.反射.person.Person 构造函数的数量:1 参数名称:arg0类型是:java.lang.String =================================================
创建对象
package com.xwtech.test.反射.person; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * @author Liyongzhe * @date 2020/12/14_14:57 */ public class CreatObject { public static Class<?> clazz; static { try { clazz = Class.forName("com.xwtech.test.反射.person.Person"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 公共默认创建对象 * @throws IllegalAccessException * @throws InstantiationException */ public void defaultFun() throws IllegalAccessException, InstantiationException { Person person = (Person) clazz.newInstance(); String name = person.getName(); System.out.println("公共默认创建对象:"+name); } /** * 公共构造指定参数类型创建对象 * @throws IllegalAccessException * @throws InstantiationException */ public void publicConstructorWithParam() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { Constructor<?> constructor = clazz.getConstructor(String.class); Person liyongzhe = (Person) constructor.newInstance("liyongzhe"); String name = liyongzhe.getName(); System.out.println("指定参数创建对象:"+name); } /** * 私有构造指定参数创建对象 * @throws NoSuchMethodException * @throws IllegalAccessException * @throws InvocationTargetException * @throws InstantiationException */ public void constructorWithParam() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Constructor<?> protectConstructor = clazz.getDeclaredConstructor(char.class); Person liyongzhe_char = (Person) protectConstructor.newInstance('男'); char sex = liyongzhe_char.sex; System.out.println("liyongzhe_char sex :" + sex); System.out.println("========================================================"); Constructor<?> privateConstructor = clazz.getDeclaredConstructor(Integer.class); //暴力访问 privateConstructor.setAccessible(true); Person liyongzhe_Integer = (Person) privateConstructor.newInstance(18); Integer age = liyongzhe_Integer.getAge(); System.out.println("liyongzhe_Integer age :" + age); System.out.println("========================================================"); Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, Integer.class); Person liyongzhe_name_age = (Person) constructor.newInstance("liyongzhe",18); String name = liyongzhe_name_age.getName(); Integer age1 = liyongzhe_name_age.getAge(); System.out.println("liyongzhe_name:"+name+","+"liyongzhe_age:"+age1); System.out.println("========================================================"); Constructor<?> publicConstructor = clazz.getDeclaredConstructor(String.class); Person liyongzhe_name = (Person) publicConstructor.newInstance("liyongzhe"); String name1 = liyongzhe_name.getName(); System.out.println("liyongzhe_name1:" + name1); } public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException { CreatObject creatObject = new CreatObject(); // creatObject.defaultFun(); // creatObject.publicConstructorWithParam(); creatObject.constructorWithParam(); } }
输出结果 - 公共默认构架对象 public Person() 公共默认创建对象:default - 公共构造指定参数类型创造对象 public Person(String name) 指定参数创建对象:liyongzhe - 私有构造指定参数创建对象 protected Person(char sex) liyongzhe_char sex :男 ======================================================== private Person(Integer age) liyongzhe_Integer age :18 ======================================================== Person(String name,Integer age) liyongzhe_name:liyongzhe,liyongzhe_age:18 ======================================================== public Person(String name) liyongzhe_name1:liyongzhe
获取成员变量
打印结果 - 获取公共的成员变量