从字符串加载类

Use*_*er1 27 java reflection

我想通过String的值来实例化一个类.我找到了几个教程,展示了这样做的几种方法.该类必须从某个接口继承,该接口ImplementMe有一个名为的特殊方法runMe().所以这就是我尝试过的:

ImplmentMe a =
   (ImplementMe) ImplementMe.class
                   .getClassLoader()
                   .loadClass("my.package.IImplementedYou")
                   .newInstance();
a.runMe();
Run Code Online (Sandbox Code Playgroud)

它有效,但它太难看了.我至少预计不需要演员.请告诉我有更好的方法.

Sea*_*oyd 36

不,没有更好的方法(按设计).你不应该这样做,Java被设计为一种类型安全的语言.但是,我可以理解你有时需要做这样的事情,为此你可以创建一个像这样的库函数:

public <T> T instantiate(final String className, final Class<T> type){
    try{
        return type.cast(Class.forName(className).newInstance());
    } catch(InstantiationException
          | IllegalAccessException
          | ClassNotFoundException e){
        throw new IllegalStateException(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您的客户端代码至少可以调用此方法而不需要转换:

MyInterface thingy =
    instantiate("com.foo.bar.MyInterfaceImpl", MyInterface.class);
Run Code Online (Sandbox Code Playgroud)

  • 你不需要未经检查的演员阵容。只需使用“return type.cast(Class.forName(className).newInstance());”即可。优点是它会立即抛出(它更快速失败)。 (2认同)

kpr*_*vas 13

试试Class.forName("my.package.IImplementedYou").

  • 你可能会注意到他仍然需要演员. (5认同)

Ask*_*eks 6

我是这样做的:

ImplementMe noCastNeeded = 
    this.getClassLoader()
        .loadClass("my.package.IImplementedYou")
        .asSubclass(ImplementMe.class).newInstance();
Run Code Online (Sandbox Code Playgroud)

有一些例外可以捕获,但我认为这没关系.:)