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
请详细解释
注:
您必须创建对象的新实例(使用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")
获取clazz
对象中pkg.SBI
类的引用。 - 由于
clazz
持有对SBI
的引用,所以调用clazz.newInstance();
与调用new SBI();
是一样的。 - 调用
clazz.newInstance();
之后,变量obj
将接收一个SBI
实例。 - 当你想调用
SBI
方法和obj
的类型是Object
(这是newInstance()
方法的返回类型),你必须将其强制转换为SBI
,然后才调用connect()
。
使用Java的反射API:
如果你想更进一步,甚至不做转换(这样LooseCouplingTest
就不需要导入SBI
),你可以使用Java的反射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);
}
}
Class.forName()
加载类。加载类的一部分是执行静态初始化块。这就是为什么你看到"Hello from SBI static"打印出来(static { ... }
部分是静态初始化块)。
要使"Connected To SBI"出现,您必须创建该类的实例并在其上调用connect()
方法:
Class<? extends Bank> bankClass = (Class<? extends Bank>)Class.forName(className);
Bank bank = bankClass.newInstance();
bank.connect();