运行结果: 出现这类错误的是因为通过new关键字创建的对象是静态加载的,意思就是在编译阶段就会被创建,可是现在还不存在Word类和Excel类,所以无法通过编译 解决方法是变动态加载为静态加载,即使用Java反射机制,具体实现如下: 先说一句帮助大家理解的话:在Java中万事万物皆对象,那么我们自己写的类也是对象,是Java中Class类的对象
class Office { public static void main(String[] args) { if("Word".equals(args[0])) { try{ //调用Class类的forName方法,根据类名获取反射 Class c1 = Class.forName("Word"); //调用Class类的newInstance方法创建对象 Word w =(Word) c1.newInstance(); }catch(Exception e){ e.printStackTrace(); } //Word w = new Word(); //w.start(); } if("Excel".equals(args[0])){ //Excel e = new Excel(); //e.start(); } } }运行结果: 这样程序编译的时候就不会报错了,因为现在的对象是在运行阶段创建的,只有当你用到某个类的实例对象时该对象才会被创建。 那么如何实现程序的的进一步解耦呢,同样举例说明: 首先,我们需要创建一个接口类来制定一个人统一的标准
interface OfficeAble { public void start(); }然后让Word类和Excel类来实现这个接口 Word类:
class Word implements OfficeAble { public void start() { System.out.println("word starts"); } }Excel类:
class Excel implements OfficeAble { public void start() { System.out.println("excel starts"); } }然后是修改后的Office类:
class OfficeBetter { public static void main(String[] args) { try{ //根据传入的参数创建该参数的反射(官网称为类类型) Class c1 = Class.forName(args[0]); //上转型,创建传入参数类的实例对象 OfficeAble oa =(OfficeAble)c1.newInstance(); oa.start(); } catch(Exception e) { e.printStackTrace(); } } }运行结果: 通过将类型参数化就实现了等号右边的解耦,可以根据需要调用的类的不同创建不同类的实例化对象,这样以后不管你其他的类怎么改动都不需要再改动此处代码。