反射在Spring等框架代码中频繁被使用到,但在我们日常做业务开发的时候就较少用的,但是通过使用反射,还是可以在很大程度上降低代码编写的复杂度和冗余度的,今天我们来聊一聊反射创建对象的方式。
一、newInstance
反射创建对象就是要调用newInstance方法,我们大家在平时自己创建对象的时候都知道要用new关键字,它就是通过调用构造函数去实例化一个对象的,那么反射也是如此,newInstance的背后就是调用构造函数。
二、获取Class类对象
假如我们在创建类A的对象的时候,就要执行new A()就可以了,用反射的时候我们也需要去获取A这个类的Class类对象才能使用反射提供的方法,然后去创建对象。
获取Class类对象的几种方式
这里我们用MyTestEntity这个类举例
- Class.forName("com.ctrip.market.statistic.web.MyTestEntity")
- MyTestEntity.class.getClassLoader().loadClass("com.ctrip.market.statistic.web.MyTestEntity")
- new MyTestEntity().getClass()
- MyTestEntity.class
效果如图:
可以看到以上四种方式获取的Class类对象都是一个地址Class@855,所以这几种方式获取Class类对象都是一致的。
三、两种反射创建对象的方式
获取到了Class类对象我们可以利用反射的方式去创建实例了。还是以MyTestEntity为例。
两种反射创建对象的方式:
1、通过构造器创建
//1、getDeclaredConstructor获取类无参构造器Constructor declaredConstructor1 = MyTestEntity.class.getDeclaredConstructor();//调用构造器的newInstance方法创建对象MyTestEntity myTestEntity = declaredConstructor1.newInstance();//2、getDeclaredConstructor获取带参的构造器Constructor declaredConstructor2 = MyTestEntity.class.getDeclaredConstructor(String.class, int.class);MyTestEntity emily = declaredConstructor2.newInstance("Emily", 10);//3、getDeclaredConstructor获取私有构造器Constructor declaredConstructor2 = MyTestEntity.class.getDeclaredConstructor(String.class, String.class);//由于是私有的构造器直接创建对象会报错can not access a member of class com.ctrip.market.statistic.web.MyTestEntity with modifiers "private"//因此需要修改访问权限declaredConstructor2.setAccessible(true);MyTestEntity emily2 = declaredConstructor2.newInstance("Emily", "女");
2、通过Class类对象直接创建
//只能调用无参构造函数MyTestEntity myTestEntity = MyTestEntity.class.newInstance();
总结:
- 通过构造器创建对象可以调用自定义的有参构造函数,Class对象方式创建只能调用默认的无参构造函数创建对象
- 通过构造器创建对象可以调用非public类型方法,通过修改访问权限的方式可以获取private类型的构造器去创建对象
- Spring等框架都用的构造器的方式创建对象,更加灵活方便