在使用反射加载类时避免ClassNotFoundException



我试图通过使用方法Class.forname("classname")的反射动态加载类,如下面的代码所示。

Class<? extends Layout> layoutClassName;
try {
    layoutClassName = (Class<? extends Layout>)   Class.forName(site.getSiteLayout());
} catch (ClassNotFoundException e) {
    layoutClassName= DefaultLayout.class;
}

我试图动态加载一个类,如果它是由登录用户(db配置)定义的,否则提供默认实现。

这工作得很好,但是经过统计分析,我们发现大约80%的时间使用默认实现。

这意味着大约80%的时候会创建一个Exception对象。由于创建异常对象是繁重的,我希望避免它,并使用一些其他逻辑来识别类是否存在。

请建议。

PS:我不是在寻找任何显著的性能提升,我只是想清理我现有的代码。

我不知道是否有一种方便的方法来检查类是否存在而不抛出ClassNotFoundException,这将适用于一般情况。

在这种情况下处理ClassNotFoundException似乎是适当的和明确的。有几个早期的问题,都建议处理异常:1,2,3

但是如果你真的想:

  • 动态加载布局(所以,你不能避免反射);
  • 通过不受限制的类名加载布局(如果没有配置,无法构建所有布局类的定义和相对稳定的列表);
  • 最小化ClassNotFoundException

,然后我可以建议缓存布局类。如果你没有大量不同的布局,像这样的东西可能会起作用:

private HashMap<String, Class<? extends List>> layoutsByName  = new HashMap<>();
public Class<? extends Layout> getLayout(String name) {
    Class<? extends Layout> layoutClass = layoutsByName.get(name);
    if(layoutClass!=null) {
        return layoutClass;
    }
    layoutClass = getLayoutUsingReflection(name);
    layoutsByName.put(name, layoutClass);
    return layoutClass;
}
private Class<? extends Layout> getLayoutUsingReflection(String name) {
    try {
        return (Class<? extends Layout>) Class.forName(name);
    } catch (ClassNotFoundException e) {
        return DefaultLayout.class;
    }
}

如你所说…

我试图动态加载一个类,如果它是定义在配置

是否在某个文件中提到了"配置"。

我希望您可以获得配置文件(或配置状态),并且仅在提到这样做时才为类创建对象。如果没有,应用默认实现。

如果你不能访问配置,恐怕没有其他的方法,据我所知。

相关内容

  • 没有找到相关文章