与Class.forName()的松散耦合

时间:2013-04-14 06:00:31

标签: java reflection loose-coupling

interface Bank {
    void connect();
}

class SBI implements Bank {
    static{
        System.out.println("Hello from SBI static");
    }   
    public void connect() {
        System.out.println("Connected to SBI");
    }
}

class LooseCouplingTest {
    public static void main(String... args)throws Exception {
        String className = args[0];
        Class.forName(className);
    }
}

上述代码的输出似乎是
Hello from SBI static

我应该将哪些内容添加到我的代码中,并将Y添加到also打印语句
Connected to SBI

详细解释非常感谢

P.S。 Noob在这里

2 个答案:

答案 0 :(得分:4)

您必须创建对象的新实例(使用Class#newInstance()),将其强制转换为您想要的类型(在您的方案SBI中),然后调用它。

工作代码:

public class LooseCouplingTest {
    public static void main(String... args)throws Exception {
        String className = args[0];
        Class<?> clazz = Class.forName(className);
        Object obj = clazz.newInstance();
        SBI mySBI = (SBI) obj;
        mySBI.connect();
    }
}

<强>解释

  • Class.forName("pkg.SBI")获取pkg.SBI对象中clazz类的引用。
  • 由于clazz包含对SBI的引用,调用clazz.newInstance();与调用new SBI();相同。
  • 调用clazz.newInstance();后,变量obj将收到SBI个实例。
  • 由于您要调用SBI方法并且obj的类型为Object(这是newInstance()方法的返回类型),您必须将其强制转换为{{ 1}}然后只调用SBI

使用Java的Reflection API:

如果您希望更进一步,甚至不进行演员表演(这种方式connect()永远不需要导入LooseCouplingTest),您可以使用 Java's Reflection API 调用SBI方法。

以下是该工作代码:

connect()

答案 1 :(得分:1)

Class.forName()加载课程。加载类的一部分是执行静态初始化程序块。这就是为什么你看到打印出“Hello from SBI static”的原因(static { ... }部分是静态初始化程序块)。

要显示“已连接到SBI”,您必须创建该类的实例并在其上调用connect()方法:

Class<? extends Bank> bankClass = (Class<? extends Bank>)Class.forName(className);
Bank bank = bankClass.newInstance();
bank.connect();