Java反射机制是Java中很重要的一部分,通过反射可以用另一种,不同于new()的实例化类对象的方法。不用Import导包,用Qualified Name 的字符串实例化对象。(forName()方法) 下面代码通过两种方法实例化Date对象。
import java.util.Date; public class Fs { public static void main(String[] args) { Date date = new Date(); //通过正常方式实例化对象 System.out.println(date); try { Class<?> cls = Class.forName("java.util.Date"); //通过反射实例化Date类对象。 Date date2 = (Date)cls.newInstance(); System.out.println(date2); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
那么问题来了,原本一行 Date date = new Date(); 就解决的问题,用了反射变成了好几行,还必须要异常处理。岂不是自找麻烦,那么反射机制的意义何在呢?
之前了解过一点工厂设计模式,在“客户端”通过Factory获得不同类的对象,达到了解耦和。但是以前的工厂设计模式有一定的设计缺陷,观察下面代码的Factory类。在每次新增Car的子类时,都需要修改Factory类来适应改变。但是当Car子类增加的速度非常快的时候,Factory类来不及更改,怎么办?就算来得及更改,那么也会产生大量的代码。这时候反射机制的优势就能体现出来了。对比一下Factory2类的产生对象的方式,便可知道反射机制的优势。
package com.jmd.bingo; interface Car { public void drive(); } class Benz implements Car { public Benz() {} @Override public void drive() { System.out.println("---开奔驰---"); } } class Audi implements Car { public Audi() {} @Override public void drive() { System.out.println("---开奥迪---"); } } class Factory { public static Car getInstance(String carname) { if("Benz".equalsIgnoreCase(carname)) { return new Benz(); } else if("Audi".equalsIgnoreCase(carname)){ return new Audi(); }else { return null; } } } class Factory2 { public static Car getInstance(String classname) { Car car = null; try { Class<?> cls = Class.forName(classname); car = (Car)cls.newInstance(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return car; } } public class FsTest { public static void main(String[] args) { Car mycar1 = Factory.getInstance("benz"); mycar1.drive(); Car mycar2 = Factory2.getInstance("com.jmd.bingo.Audi"); mycar2.drive(); } }
输出结果:
---开奔驰---
---开奥迪---