目录
注意: 在没有添加有参构造器之前,程序会自动调用一个无参构造器,当我们添加了有参构造器后,需要我们手动添加一个无参构造器
一.什么是反射
反射是Java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法
二、类对象的获取
1.获取方式:
1.Class.forName
2.类实例.getClass
3.类名.class
2.案例演示:
package com.YU; /** * 类对象的获取方式: * 1.Class.forName * 2.类实例.getClass * 3.类名.class * @author 21879 * */ public class Demo1 { public static void main(String[] args) throws Exception { //1.Class.forName Student stu = new Student(); Class c1 = Class.forName("com.YU.Student"); System.out.println(c1); //2.类实例.getClass Class c2 = stu.getClass(); System.out.println(c2); //3.类名.class Class c3 = Student.class; System.out.println(c3); } }
运行结果:
class com.YU.Student class com.YU.Student class com.YU.Student
3.通用场景
(1):第一种 : 通常应用在jdbc连接数据库链接中
(2):第二种 : 通常应用在通用增删改
(3):第三种: 通用查询
三.反射实例化
1.首先
理解一个概念,所有的反射从类对象开始
代码部分 :
package com.YU; /** * 反射实例化 * * @author 21879 * */ public class Demo2 { public static void main(String[] args) throws Exception { //一切的反射从类对象开始 Class c1 = Class.forName("com.YU.Student"); Student stu = (Student) c1.newInstance(); System.out.println(stu); } }
运行结果:
com.YU.Student@7852e922
注意: 在没有添加有参构造器之前,程序会自动调用一个无参构造器,当我们添加了有参构造器后,需要我们手动添加一个无参构造器
场景演练:
public static void main(String[] args) throws Exception { //一切的反射从类对象开始 Class c1 = Class.forName("com.YU.Student"); Student stu = (Student) c1.newInstance(); System.out.println(stu); }
1.有无参构造器和有参构造器的情况下
输出结果:
2.没有无参构造器和有参构造器的情况下
输出结果
程序报错:
Exception in thread "main" java.lang.InstantiationException: com.YU.Student at java.lang.Class.newInstance(Unknown Source) at com.YU.Demo2.main(Demo2.java:13) Caused by: java.lang.NoSuchMethodException: com.YU.Student.<init>() at java.lang.Class.getConstructor0(Unknown Source) ... 2 more
在这里我们就需要手动去添加无参构造器
2.分别调用有参构造器和无参构造器反射实例化
(1):调用无参构造器反射实例化
Class c1 = Class.forName("com.YU.Student"); //调用无参构造器反射实例化 Student stu = (Student) c1.newInstance(); System.out.println(stu);
运行结果:
调用无参构造方法创建了一个学生对象
com.YU.Student@7852e922
(2):调用有参构造器反射实例化
Class c1 = Class.forName("com.YU.Student"); Constructor cr1 = c1.getConstructor(String.class); Student stu1 = (Student) cr1.newInstance("s001"); System.out.println(stu1);
运行结果:
调用带一个参数的构造方法创建了一个学生对象
com.YU.Student@4e25154f
(3):调用多个参数的构造器反射实例化
//调用多个参数的构造器反射实例化 Class c1 = Class.forName("com.YU.Student"); Constructor cr2 = c1.getConstructor(String.class,String.class); Student stu2 = (Student) cr2.newInstance("s001","666"); System.out.println(stu2);
运行结果:
调用带二个参数的构造方法创建了一个学生对象
com.YU.Student@70dea4e
(4):调用私有的带有一个参数的构造器实例化
//调用私有的带有一个参数的构造器实例化 Constructor cr3 = c1.getDeclaredConstructor(Integer.class); cr3.setAccessible(true); Student stu3 = (Student) cr3.newInstance(18); System.out.println(stu3);
运行结果:
调用Student类私有的构造方法创建一个学生对象
com.YU.Student@5c647e05
这里需要注意的是,我们在调用私有的构造器实例化时,
需要先打开私有构造器的方法:cr3.setAccessible(true);
不然会报出以下错误:
Exception in thread "main" java.lang.IllegalAccessException: Class com.YU.Demo2 can not access a member of class com.YU.Student with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Unknown Source) at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source) at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at com.YU.Demo2.main(Demo2.java:30)
这里就需要加上以上打开私有构造器代码