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晓码阁 版权所有