与Class.forName()的松散耦合

Sri*_*aru 5 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我应该添加什么来代码和Y来also打印语句
Connected to SBI

详细解释非常感谢

PS Noob在这里

acd*_*ior 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

解释:

  • Class.forName("pkg.SBI")pkg.SBI获取对象中类的引用clazz
  • Asclazz持有对 的引用SBI,调用clazz.newInstance();与调用: 相同new SBI();
  • 调用后clazz.newInstance();,变量obj将收到一个SBI实例。
  • 当您想要调用一个SBI方法并且obj的类型是Object(即该newInstance()方法的返回类型)时,您必须将其转换为SBI然后才调用connect()

使用 Java 的反射 API:

如果您希望更进一步,甚至不进行强制转换(这种方式LooseCouplingTest永远不需要 import SBI),您可以使用Java 的 Reflection API来调用该connect()方法。

这是其工作代码:

public class LooseCouplingTest {
    public static void main(String... args) throws Exception {
        String className = args[0];
        Class<?> clazz = Class.forName(className);
        Object obj = clazz.newInstance();
        java.lang.reflect.Method connect = clazz.getMethod("connect");
        connect.invoke(obj);
    }
}
Run Code Online (Sandbox Code Playgroud)