3

我得到了大约 20 个名称为 A、B、C、...X、Y、Z 的课程。

用户会向我发送一些消息,我将根据消息的内容选择其中一个类进行实例化。该消息与其相应类的名称相同。

我可以编写一个 switch case 语句来执行此操作,例如:

switch (msg):
  case "A" :
    class = new A();
    break;
  case "B" :
    class = new B();
    break;
  case "C" :
    class = new C();
    break;
...

有没有更简洁的方法来做到这一点?如果我有 1000 个课程,我无法想象编码是多么无聊。

4

6 回答 6

3

您可以Class.forName()为此使用:

Class c = Class.forName("foo.bar.MyClass"); // requires full class name including package
Object object = c.newInstance();

有关详细信息,请参阅文档。Class.forName()这些特征称为反射。Oracle 为这些特性提供了一个很好的文档部分

于 2013-09-02T20:03:54.130 回答
2

其他人建议使用工厂,他们是对的。

我更喜欢enum为我的工厂使用一个。

interface I {

}

class A implements I {

}
class B implements I {

}
class C implements I {

}
enum Factory{
  A {
    @Override
    A create() {
     return new A(); 
    } 
  },
  B {
    @Override
    B create() {
     return new B(); 
    } 
  },
  C {
    @Override
    C create() {
     return new C(); 
    } 
  };

  // Constructors.
  abstract I create();

  // Construct a named class.
  public I create(String type) {
    return Factory.valueOf(type).create();
  }
}
于 2013-09-02T21:27:20.727 回答
1

试试这个: -

Class myclass = Class.forName("Your.Class.MyClass");
Object o= myclass .newInstance();

名称()

返回与具有给定字符串名称的类或接口关联的 Class 对象。

于 2013-09-02T20:04:38.160 回答
0
  1. 从 a获取Class实例ClassLoader,传入您需要的名称。
  2. 调用newInstance它。
于 2013-09-02T20:03:53.277 回答
0

正如我看到每个人都有自己的解决方案,所以我告诉你我的

你需要:

    interface MyInterface {
    }

    class A implements MyInterface {
    }

    class B implements MyInterface {
    }

    interface Factory {
    MyInterface createInstance();
}

    class FactoryA implements Factory {

    @Override
    public MyInterface createInstance() {
        return new A();
    }
}

class FactoryB implements Factory {

    @Override
    public MyInterface createInstance() {
        return new B();
    }
}

enum MyEnum {
    A(new FactoryA()), B(new FactoryB());
    Factory factory;

    MyEnum(Factory factory) {
        this.factory = factory;
    }

    MyInterface getInstance() {

        return factory.createInstance();

    }

}

那么您需要做的就是创建查找表,您的 switch 语句将被替换为MyEnum.find(msg).getInstance()

使用此解决方案,您无需担心处理任何异常

于 2013-09-02T20:41:03.167 回答
0

首先,这类问题是好的设计所固有的。您正在谈论的那种方法是Factroy Method

您可以使用 case,但更典型的是使用 if-else 块。所以...

if(msg.equals(A)) {
  return new A();
} else if(msg.equals(B)) {
  return new B();
} ....

这里假设 A & B 是字符串,我喜欢将它们定义为常量 ( public static final)。

虽然两者都有点混乱,但大多数时候人们使用 if-else 块,它是更标准的过程。

于 2013-09-02T20:12:02.357 回答