[英]Loose coupling with Class.forName()
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);
}
}
The output for the above code appears to be 上面代码的输出似乎是
Hello from SBI static
What should I add to my code and Y to also
print the statement 我应该添加到我的代码和Y到also
打印声明
Connected to SBI
In detail explanation is much appreciated 详细解释非常感谢
PS Noob here PS Noob在这里
You have to create a new instance of the object (using Class#newInstance()
), cast it to the type you want (in your scenario SBI
), and then call it. 您必须创建一个新的对象实例(使用Class#newInstance()
),将其Class#newInstance()
为所需的类型(在方案SBI
),然后调用它。
Working code: 工作代码:
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();
}
}
Explanation: 说明:
Class.forName("pkg.SBI")
gets a reference for pkg.SBI
class in the clazz
object. Class.forName("pkg.SBI")
获取clazz
对象中pkg.SBI
类的引用。 clazz
holds a reference to SBI
, calling clazz.newInstance();
由于clazz
拥有对SBI
的引用,因此调用clazz.newInstance();
is the same as calling: new SBI();
与调用相同: new SBI();
. 。 clazz.newInstance();
调用clazz.newInstance();
, then, the variable obj
will receive a SBI
instance. ,那么变量obj
将收到一个SBI
实例。 SBI
method and obj
's type is Object
(that's the newInstance()
method's return type) you have to cast it to SBI
and only then call connect()
. 当您要调用SBI
方法且obj
的类型为Object
(即newInstance()
方法的返回类型)时,必须将其SBI
为SBI
,然后再调用connect()
。 If you wish to go even further and not even do the cast (this way LooseCouplingTest
never needs to import SBI
), you can use Java's Reflection API to invoke the connect()
method. 如果您想走得更远甚至不进行LooseCouplingTest
(这样LooseCouplingTest
永远不需要导入SBI
),则可以使用Java的Reflection API来调用connect()
方法。
Here's the working code for that: 这是工作代码:
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()
loads the class. Class.forName()
加载类。 and part of loading the class is executing the static initializer block. 加载类的一部分是执行静态初始化程序块。 That's why you see "Hello from SBI static" printed (the static { ... }
part is the static initializer block). 这就是为什么您看到“从SBI静态开始的Hello”( static { ... }
部分是静态初始化程序块)的原因。
To make "Connected to SBI" appear, you have to create an instance of the class and call the connect()
method on it: 要显示“已连接到SBI”,您必须创建该类的实例并在其上调用connect()
方法:
Class<? extends Bank> bankClass = (Class<? extends Bank>)Class.forName(className);
Bank bank = bankClass.newInstance();
bank.connect();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.