经过一系列分析之后可以发现虽然获得了Class类的实例话都西昂,但是依然觉得这个对象获取的意义不是很大,所以为了进一步的帮助大家理解反射的核心意义所在,下面将通过几个案例进行程序的说明(都是在实际开发之中一定会使用到的)。
1 反射实例化对象
获取Class对象之后最大的意义实际上并不是在于只是一个对象的实例化的操作形式,更重要的是Class类里面提供有一个对象的反射实例化方法(代替了关键字new):
(1)在JDK1.9以前的实例化:@Deprecated(since="9") public T newInstance() throws InstantiationException, IllegalAccessException
(2)在JDK 1.9之后:clazz.getDeclaredConstructor().newInstance()
范例:通过newInstance()方法实例化Student类对象
package org.lks.demo;
public class JavaAPIDemo {
public static void main(String[] args) {
Class<?> cls = null;
try {
cls = Class.forName("org.lks.model.Student");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Object obj = cls.newInstance();
System.out.println(obj);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
现在通过反射实现的对象实例化处理,依然要调用类中的无参构造方法,其本质等价于“类.对象 = new 类()”,也就是相当于隐含了关键字new,而直接使用字符串进行类替代。
范例:从JDK 1.9之后newInstance()被替代了
package org.lks.demo;
import java.lang.reflect.InvocationTargetException;
public class JavaAPIDemo {
public static void main(String[] args) {
Class<?> cls = null;
try {
cls = Class.forName("org.lks.model.Student");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object obj = null;
try {
obj = cls.getDeclaredConstructor().newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(obj);
}
}
因为默认的Class类中的newInstance()方法只能够调用无参构造,所以很多开发者会认为其描述的不准确,于是将其变换了形式(构造方法会讲解)
2 反射与工厂设计模式
如果要想进行对象的实例化处理除了可以使用关键字new之外,还可以使用反射机制来完成,于是此时一定会思考一个问题:为什么要提供有一个反射的实例化?那么到底是使用关键子new还是使用反射呢?
如果要想更好的理解此类问题,最好的解释方案就是通过工厂设计模式来解决。工厂设计模式的最大的特点:客户端的一个程序类不直接牵扯到对象的实例化管理,只与接口发生关联,通过工厂类获取指定接口的实例化对象。
范例:传统模式
package org.lks.demo;
public class JavaAPIDemo {
public static void main(String[] args) {
IMessage message = new NetMessageImpl();
message.send();
}
}
interface IMessage{
void send();
}
class NetMessageImpl implements IMessage{
@Override
public void send() {
System.out