1. 什么是反射
反射java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法
2. 类类
所有狗 狗类 Dog 狗对象 旺财
所有猫 猫类 Cat 猫对象 肥波
所有类 类类 java.lang.Class 类对象 特定类
student.java
public class Student { private String sid; private String sname; public Integer age; static{ System.out.println("加载进jvm中!"); } public Student() { super(); System.out.println("调用无参构造方法创建了一个学生对象"); } public Student(String sid) { super(); this.sid = sid; System.out.println("调用带一个参数的构造方法创建了一个学生对象"); } public Student(String sid, String sname) { super(); this.sid = sid; this.sname = sname; System.out.println("调用带二个参数的构造方法创建了一个学生对象"); } @SuppressWarnings("unused") private Student(Integer age) { System.out.println("调用Student类私有的构造方法创建一个学生对象"); this.age = age; } public String getSid() { return sid; } public void setSid(String sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public void hello() { System.out.println("你好!我是" + this.sname); } public void hello(String name) { System.out.println(name + "你好!我是" + this.sname); } @SuppressWarnings("unused") private Integer add(Integer a, Integer b) { return new Integer(a.intValue() + b.intValue()); } }
3. 一切反射相关的代码都从获得类对象开始
3.1 Class.forName(完整类名)
3.2 类名.class
3.3 对象.getClass()
注1:ClassNotFoundException(类名错|少jar包)
注2:同一类的、类对象只会创建一个
public static void main(String[] args) throws ClassNotFoundException { // 自定义MVC框架做通用增删改的时候会用 Student stu1 = new Student(); Class stuClz1 = stu1.getClass(); // 配合框架配置文件建模使用 Class stuClz2 = Class.forName("com.javaxl.entity.Student"); // 自定义MVC框架做通用的查询时候会用到 Class stuClz3 = Student.class; System.out.println(stuClz1); System.out.println(stuClz2); System.out.println(stuClz3); // 打印语句会告诉我们,同一类的、类对象只会创建一个 }
4. 反射三大作用(java.lang.reflect.*)
4.1 实例化对象
c.newInstance()
Constructor.getConstructor/Constructor.getDeclaredConstructor
注:一定要提供无参构造器
核心代码
/* * 1、讲解传统实例化与反射实例化的区别 * 2、web.xml能够加载servlet的原理 * web.xml建模 * 通过URL找到对应的servlet全限定名,然后获取类对象,通过类对象实例化, * 由于servlet都继承与httpservlet,向上转型,那么自然就具备了servlet接口的功能 * 3、后期很多框架都需要填写全限定名,也是为了获取类对象,进行实例化 */ Class c1 = Class.forName("com.javaxl.entity.Student"); // 直接实例化对象 // Student student = (Student) c1.newInstance();
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { Student stu1 = new Student(); Class<? extends Student> clz1 = stu1.getClass(); // 调用无参的构造器 // Student inst1 = clz1.newInstance(); Constructor<? extends Student> c1 = clz1.getDeclaredConstructor(); c1.newInstance(); // 调用一个String参数的构造器 Constructor<? extends Student> c2 = clz1.getDeclaredConstructor(String.class); c2.newInstance("s001"); // 调用二个个String参数的构造器 Constructor<? extends Student> c3 = clz1.getDeclaredConstructor(String.class,String.class); c3.newInstance("s001","s002"); // 调用一个Integer参数的构造器 Constructor<? extends Student> c4 = clz1.getDeclaredConstructor(Integer.class); // 一定记得打开访问权限 c4.setAccessible(true); c4.newInstance(100); }
4.2 动态调用方法
Method m;
m.invoke
核心代码
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Student stu = new Student(); Class<? extends Student> clz = stu.getClass(); // 无参方法调用 Method m1 = clz.getMethod("hello"); m1.invoke(stu); // 带一个String参数的方法调用 Method m2 = clz.getMethod("hello",String.class); m2.invoke(stu,"小李飞刀"); // 带二个Integer参数的私有方法调用 Method m3 = clz.getDeclaredMethod("add",Integer.class,Integer.class); m3.setAccessible(true); m3.invoke(stu,100,20); }
4.3 读写属性
Field set/get
核心代码
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Student stu = new Student("s001","小李飞刀"); stu.age = 27; Class<? extends Student> clz = stu.getClass(); // 读写共有属性age Field f1 = clz.getField("age"); System.out.println(f1.get(stu)); // 读取私有属性name Field f2 = clz.getDeclaredField("sname"); f2.setAccessible(true); System.out.println(f2.get(stu)); // 获取Student类中的所有属性的属性名以及属性值 Field[] fields = clz.getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); System.out.println(f.getName() + ":" + f.get(stu).toString()); } }
5. 访问修饰符
getModifiers()
备案号:湘ICP备19000029号
Copyright © 2018-2019 javaxl晓码阁 版权所有