java - 使用反射加载类时避免 ClassNotFoundException

标签 java exception if-statement reflection classloader

我正在尝试使用以下代码中给出的方法 Class.forname("classname") 通过反射动态加载类。

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

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

这工作正常,但经过统计分析,我们发现大约 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;
    }
}

这样您就不会两次检查相同的布局。

关于java - 使用反射加载类时避免 ClassNotFoundException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31935324/

相关文章:

java - jjs.exe 和 ServiceLoader

java - 如何对我想要作为查询字符串传递的 URL 进行编码

java - JSF "Remember me"选项

java - com.sun.mail.smtp.SMTPSendFailedException : 530 5. 7.0 必须首先发出 STARTTLS 命令

c++ - 未捕获 WM_PAINT 中的访问冲突

java - 如何将 if/else if 代码中的整数转入该代码外部的整数? (java)

java - 使用 Woodstox 解析 XML 时保持实体不变

c# - 捕获异常后继续程序?

java - 当 "if"语句以分号结束时会发生什么

javascript - 请帮助找出为什么代码以这种方式工作(JavaScript)