我需要实例化两种不同类型之一的对象,这取决于条件。这两种类型的构造函数都有相同的参数,并且都是主类型的子类。是否可以在条件中定义对正确类型的引用,然后使用该引用实例化对象?快速示例:
if (v == "bob") {
Object myType = bobType;
} else {
Object myType = otherType;
}
SuperType instance = new myType(arg1, arg2);这是行不通的;在java中有正确的语法吗?这是完成此操作的快捷方式:
if (v == "bob") {
SuperType instance = new bobType(arg1, arg2);
} else {
SuperType instance = new otherType(arg1, arg2);
}我实际上做了几个实例,都是同一类型的,都有一个很长的参数列表,我想避免重复我自己,除了类型。
发布于 2012-10-10 08:23:35
可以使用反射来实现这一点,但在大多数情况下,定义工厂会更惯用。例如,
interface MyFactory {
SuperType newInstance(Foo arg1, Bar arg2);
}
class BobFactory implements MyFactory {
public BobType newInstance(Foo arg1, Bar arg2) {
return new BobType(arg1, arg2);
}
}
class OtherFactory implements MyFactory {
public OtherType newInstance(Foo arg1, Bar arg2) {
return new OtherType(arg1, arg2);
}
}
void myMethod() {
MyFactory factory;
if (v == "bob") {
factory = new BobFactory();
} else {
factory = new OtherFactory();
}
SuperType instance = factory.newInstance(arg1, arg2);
}这比您想象的更冗长,但它的优点是,如果您更改了BobType或OtherType的构造函数,编译器将捕捉到您需要更新此代码,而不是在运行时崩溃。
发布于 2012-10-10 08:17:14
您可以,但您必须使用反射API。有没有什么原因你不能这样写:
SuperType instance;
if (v == "bob") {
instance = new bobType(arg1, arg2);
} else {
instance = new otherType(arg1, arg2);
}否则,您需要的是使用Class类型来获取对构造函数的引用,然后您可以直接调用构造函数:
SuperType instance;
Class<? extends SuperType> clazz;
Constructor<? extends SuperType> constructor;
if ("bob".equals(v)) {
clazz = bobType.class;
} else {
clazz = otherType.class;
}
//subbing in types of arg1 and arg2 of course
constructor = class.getConstructor(String.class, String.class);
instance = constructor.newInstance(arg1, arg2);因此,如果您的目标只是简洁,那么它也不会太冗长,而且反射抛出了您需要处理的各种检查过的异常。如果你在编译时知道所有可能的类型,那就没有什么好处了。如果您不知道所有的类型,并且正在通过名称从其他库中查找类,那么它将变得非常有用。
发布于 2012-10-10 08:17:36
这在java中有点复杂,你需要使用类名来创建一个实例。看一下这个问题:Creating an instance using the class name and calling constructor
https://stackoverflow.com/questions/12810191
复制相似问题