目录
- 1. 什么是反射,为何用它
- 2. Student类
- 3. Person类
- 4. 反射实现
以测试学生类为主
1. 什么是反射,为何用它
1.1 什么是反射:允许程序员在程序运行期间动态的获得某个类型的信息(类本身的信息以及类的成员信息),从而开发出更为灵活通用的代码
反射能做什么,例如:
- String className = “com.hr.entity.Student”;
使用上面的字符串变量值创建出其对象的对象 - 类中的私有属性和方法如何去调用
1.2. 反射操作的前提条件:
1.2.1 获得一个类型对应的类对象
// 1. 类.classClass<Student> stu = Student.class;Student student = new Student();// 2. 对象.getClass()Class<?> class1 = student.getClass();try {// Class.forName("类的路径")Class<?> class2 = Class.forName("com.lovely.reflect.Student");} catch (ClassNotFoundException e) {e.printStackTrace();}
1.2.2 什么是类对象?
即Class这个类的对象,该对象就是用来描述一个类型的基本信息以及该类型中所有的成员信息
1.2.3 如何在java中获取类对象?
- 类.class 在编译期类型就已经定死了,但写法最简单
- 对象.getClass()在编译期类型就已经定死了
- Class.forName(“类型全路径”) 写法麻烦,字符串类型容易写错,但是此写法灵活
2. Student类
```java
package com.lovely.reflect;import java.io.Serializable;import javax.management.RuntimeErrorException;public class Student extends Person implements Serializable {private static final long serialVersionUID = 1L;private Integer id;private String name;public Integer age;public Student() {}Student(String name, Integer age) throws RuntimeErrorException, Exception {this.name = name;this.age = age;}public Student(Integer id, String name, Integer age) {this.id = id;this.name = name;this.age = age;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}void show() {String str = study("odorable");System.out.println(str);}public void show(String name) {this.name = name;System.out.println("我是" + name);}private String study(String name) {return name + "要学习。";}@Overridepublic String toString() {return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";}}
3. Person类
package com.lovely.reflect;public class Person {private String name;public Integer age;public Person() {this.age = 100;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}void show() {}}
4. 反射实现
package com.lovely.reflect;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;public class Test1 {public static void main(String[] args) {// testClassInfo();// testConstructor();// testCharacter();testMethod();}@SuppressWarnings("rawtypes")static void testClassInfo() {// 反射得到类加载的信息Student stu = new Student();Class stuClass = stu.getClass();// 访问修饰符System.out.println(stuClass.getModifiers()); // 返回修饰符所对应的数字System.out.println("此类修饰符是:" + Modifier.toString(stuClass.getModifiers()));// 类的路径 和 类名System.out.println(stuClass.getName() + "\t" + stuClass.getSimpleName());// student所在的包名Package pkg = stuClass.getPackage();System.out.println(pkg.getName());// student 的父类名Class superClass = stuClass.getSuperclass();System.out.println("stu父类:" + superClass.getSimpleName());while (true) {if (stuClass != null) {System.out.println("学生类的继承体系:" + stuClass.getName());stuClass = stuClass.getSuperclass();} else {break;}}// 创建类对象try {stuClass = stu.getClass();stu = (Student) stuClass.newInstance();System.out.println(stu);} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}System.out.println("学生类实现的接口类型:");Class[] interfaces = stuClass.getInterfaces();for (Class inter : interfaces) {System.out.println(inter);}}static void testConstructor() {// 反射得到类的构造信息Class<Student> stuClass = Student.class;try {// getConstructor() 只可拿到public的构造Constructor<Student> cs = stuClass.getConstructor();Student stu = cs.newInstance();System.out.println(stu);System.out.println(cs.getModifiers() + "\t" + cs.getName());// 拿到非public构造类cs = stuClass.getDeclaredConstructor(String.class, Integer.class);// 授权访问// cs.setAccessible(true);// 用构造类创建student 对象 参数和上面对应stu = cs.newInstance("小明", 19);System.out.println(stu);// 三个构造cs = stuClass.getDeclaredConstructor(Integer.class, String.class, Integer.class);stu = cs.newInstance(1, "point", 18);System.out.println(stu);System.out.println("获得构造的参数, 返回类对象数组====");cs = stuClass.getDeclaredConstructor(String.class, Integer.class);// 拿到当前构造类的 构造参数Class<?>[] parameterTypeClass = cs.getParameterTypes();for (Class<?> type : parameterTypeClass) {System.out.println(type);}System.out.println("获得异常=====");// 获得构造的异常Class<?>[] exTypes = cs.getExceptionTypes();for (Class<?> exType : exTypes) {System.out.println(exType);}} catch (Exception e) { e.printStackTrace();}}static void testCharacter() {// 反射得到类的属性信息Student stu = new Student();Class<Student> stuClass = Student.class;try {// 通过名字获取子父类中的属性对象(public)子类没有 找父类Field filed = stuClass.getField("age");// age属性的名称和修饰符System.out.println(filed.getName() + "\t" + Modifier.toString(filed.getModifiers()));filed.set(stu, 1);System.out.println("反射赋值age: " + filed.get(stu));// 通过名字获取当前类的属性对象,不管什么修饰符filed = stuClass.getDeclaredField("id");System.out.println(filed.getName() + "\t" + filed.getType() + "\t" + Modifier.toString(filed.getModifiers()));// 赋予可访问权限filed.setAccessible(true);filed.set(stu, 1);Object obj = filed.get(stu);System.out.println("反射赋值id: " + obj);System.out.println("===========");// 拿到当前类和父类的共有属性对象Field[] fs = stuClass.getFields();for (Field f : fs) {System.out.println(f.getName() + ":" + f.get(stu));}System.out.println("===========");// 拿到当前类的所有属性对象fs = stuClass.getDeclaredFields();for (Field f : fs) {f.setAccessible(true);System.out.println(f.getName() + ":" + f.get(stu));}} catch (Exception e) {e.printStackTrace();} }static void testMethod() {// 反射得到类的方法信息try {Class<?> stuClass = Class.forName("com.lovely.reflect.Student");// 获得student类指定名字和参数得方法对象 类型 getMethod只可拿到public修饰符的方法Method method = stuClass.getMethod("show", String.class);System.out.println(method);// 需要学生对象调用方法 该方法的参数值method.invoke(stuClass.newInstance(), "小明");// 下面是获得任意方法对象 方法有参数要指定参数Method method1 = stuClass.getDeclaredMethod("show");// 在Student类里面是私有的 在test1里面 利用反射想访问 得设置权限为truemethod1.setAccessible(true);Object result = method1.invoke(stuClass.newInstance());System.out.println("方法返回值为:" + result);System.out.println("=======");// study 方法对象Method method2 = stuClass.getDeclaredMethod("study", String.class);// 可以调用该非public有方法method2.setAccessible(true);// 方法对象调用方法Object study = method2.invoke(stuClass.newInstance(), "odorable");System.out.println(study);// 方法对象的修饰符 方法名 参数返回值System.out.println(Modifier.toString(method2.getModifiers()) + "\t" + method2.getName() + "\t" + method2.getReturnType());// 参数列表类型数组Class<?>[] ptypes = method2.getParameterTypes();for (Class<?> type : ptypes) {System.out.println(type);}System.out.println("============");// 获得当前类中所有方法对象Method[] methods = stuClass.getDeclaredMethods();for (Method me : methods) {System.out.println(me.getName());} System.out.println("++++++++++++++++++");// 获得当前类一直到Object类中所有public方法对象 (Student Person Object)methods = stuClass.getMethods();for (Method me : methods) {System.out.println(me.getName());}} catch (Exception e) {e.printStackTrace();}}
}
更新…