1、反射
概念:反射是java语言的一种机制,通过这种机制,可以动态的实例化对象、读取属性、调用方法。
2、获取类对象的三种方式:
a、Class.forName("完整的类名");
b、类.class();
c、类对象.getClass();
注:一切与反射相关的代码都是从获得类对象开始的。
3、类类
概念:所有的类都放在一起 泛指
例如:所有狗 狗类 Dog (泛指) 狗对象 (特指)
所有猫 猫类 Cat (泛指) 猫对象(特指)
所有类 类类 java.lang.Class 泛指 类对象(特指)
4、常见的异常:
1、java.lang.ClassNotFoundExecption 类找不到异常
出现的原因:1、类名错误 2、忘记导入jar包
2、java.lang.NoSuchMethodExecption 找不到方法异常
出现的原因:没有写这个方法
3、java.lang.IllegalArgumentException 不合法的参数异常
出现的原因:上文中带了参数 而下文要使用的地方没有带参数
5、反射的三大作用:
1、实例化对象:
例如:
//传统方式实例化对象
Student stu=new Student();
传统方式和反射机制实例化对象的区别:
前者只能写固定的,就像上面的截图所示,只能实例化Student;
而后者传完整的类名进去,可以实例化你所需要实例化的,不是固定的,因而更加方便,也可以简化代码。
反射实例化对象有无参和有参数的方法:
1、无参数的方法 使用类对象.newInstance( );
//反射机制实例化对象
Class c1=Class.forName("com.zking.Student");
//这里使用object接收 也就是对象
Student stu=(Student)c1.newInstance();
System.out.println("stu");
2、有参数的方法 使用类对象.getConstructor(数据类型.class);
Class c2=c1.getConStructor(String.class,String.class);
Student stu3=(Student) c2.newInstance("s007","LYF");
System.out.println(stu3);注意:因为上文带了两个String类型的两个参数,那么 下文也要带上两个String类型的两个参数,否则会报下面这个错误.
Constructor c2=c1.getConstructor(String.class,String.class);
Student stu3=(Student) c2.newInstance();
System.out.println(stu3);解析:这样子的代码就是有问题的,因为c2.newInstance的括号里面缺少两个String类型的参数;
报错如下图所示:

而图中的这个java.lang.IllegalArgumentExecption呢,就是上文中我写的常见的异常之一,
不合法的参数异常,而出现这个异常的原因无非是两种:
1是缺少对应的参数 2是上下文中的参数类型不匹配
OK,现在展示一下正确的代码截图:

2、动态的调用方法:
这里调用的方法也有两种,一种是私有的,一种是公开的;
1、公开的方法: 类对象.getMethod("方法名",可变参数(数组,参数));
//相关代码
Student s=new Student();
s.setSname("WULI峰峰");
System.out.println(s);
//反射机制实例化对象
Class c1=Class.forName("com.zking.Student");
Method method=c1.getMethod("hello", new Class[]{String.class});
method.invoke(s, "小汪同学");接下来给你们看一下结果!!

2、私有的方法:类对象.getDeclaredMethod("方法名",可变参数);
method.invoke(对象,“参数值”);
Method method2=c1.getDeclaredMethod("add", Integer.class,Integer.class);
method2.setAccessible(true);
Integer n=(Integer)method2.invoke(s, 24,35);
System.out.println(n);结果会输出59,因为是调用了一个add的方法
![]()
3、读取属性:
1、公开的:类对象.getField();
Student s=new Student();
System.out.println(s);
//反射机制实例化对象
Class c1=Class.forName("com.zking.Student");
//获取类对象的属性
Field agefield=c1.getField("age");
//给类对象的属性赋值
agefield.set(s, 18);
//得到类对象的值
Integer age=(Integer)agefield.get(s);
System.out.println(age);输出的结果如下图所示:

:2、私有的方法:类对象.getDeclaredField( );
Field sid=c1.getDeclaredField("sid");
sid.setAccessible(true);//开放权限
sid.set(s, "s009");
Object obj=sid.get(s);
System.out.println(obj);解析:setAccessible(true);//放开权限或者说是公开权限的意思;
如果缺少这一步的话,会报java.lang.IllegalAccessException这个异常,
就像下图所示这样:

是因为没有授权,所以这一步至关重要!
那么我们现在来看看正确的代码运行之后的结果!!!
![]()
3、set/get方法
补充知识点:访问修饰符:getModifiers();
作用:以二进制的方式将修饰符的二进制进行相加。
好啦,今天的总结就到这里,学海无涯,有什么问题或者建议欢迎私信或者评论交流噢!!!