[置顶] 在java中如何判断一个类是否存在
2017-09-30 11:09
543 查看
Apache Commons-Logging 中的解决方案:
核心的代码:
所以以上的代码对应于:
SpringMVC 中的解决方案:
可见,以上都是用了
我们所需要做的仅仅是屏蔽该异常,并设置一个表示当前类不存在的标识。
那么问题来了,我们都知道
但是
那么如下的代码似乎更符合我们的要求吧?
以上的
两者的区别见:
http://blog.csdn.net/x_iya/article/details/73199280
public class LogSource { // ------------------------------------------------------- Class Attributes static protected Hashtable logs = new Hashtable(); /** Is log4j available (in the current classpath) */ static protected boolean log4jIsAvailable = false; /** Is JDK 1.4 logging available */ static protected boolean jdk14IsAvailable = false; /** Constructor for current log class */ static protected Constructor logImplctor = null; // ----------------------------------------------------- Class Initializers static { // Is Log4J Available? try { log4jIsAvailable = null != Class.forName("org.apache.log4j.Logger"); } catch (Throwable t) { log4jIsAvailable = false; } // Is JDK 1.4 Logging Available? try { jdk14IsAvailable = null != Class.forName("java.util.logging.Logger") && null != Class.forName("org.apache.commons.logging.impl.Jdk14Logger"); } catch (Throwable t) { jdk14IsAvailable = false; } // Set the default Log implementation String name = null; try { name = System.getProperty("org.apache.commons.logging.log"); if (name == null) { name = System.getProperty("org.apache.commons.logging.Log"); } } catch (Throwable t) { } if (name != null) { try { setLogImplementation(name); } catch (Throwable t) { try { setLogImplementation("org.apache.commons.logging.impl.NoOpLog"); } catch (Throwable u) { // ignored } } } else { try { if (log4jIsAvailable) { setLogImplementation("org.apache.commons.logging.impl.Log4JLogger"); } else if (jdk14IsAvailable) { setLogImplementation("org.apache.commons.logging.impl.Jdk14Logger"); } else { setLogImplementation("org.apache.commons.logging.impl.NoOpLog"); } } catch (Throwable t) { try { setLogImplementation("org.apache.commons.logging.impl.NoOpLog"); } catch (Throwable u) { // ignored } } } } //... }
核心的代码:
boolean isPresent = null != Class.forName("org.apache.log4j.Logger");
!=的优先级大于
=
所以以上的代码对应于:
boolean isPresent = (null != Class.forName("org.apache.log4j.Logger"));
SpringMVC 中的解决方案:
public class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConverter { private static final boolean jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", AllEncompassingFormHttpMessageConverter.class.getClassLoader()); private static final boolean jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", AllEncompassingFormHttpMessageConverter.class.getClassLoader()) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", AllEncompassingFormHttpMessageConverter.class.getClassLoader()); private static final boolean jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", AllEncompassingFormHttpMessageConverter.class.getClassLoader()); private static final boolean gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", AllEncompassingFormHttpMessageConverter.class.getClassLoader()); public AllEncompassingFormHttpMessageConverter() { addPartConverter(new SourceHttpMessageConverter<Source>()); if (jaxb2Present && !jackson2XmlPresent) { addPartConverter(new Jaxb2RootElementHttpMessageConverter()); } if (jackson2Present) { addPartConverter(new MappingJackson2HttpMessageConverter()); } else if (gsonPresent) { addPartConverter(new GsonHttpMessageConverter()); } if (jackson2XmlPresent) { addPartConverter(new MappingJackson2XmlHttpMessageConverter()); } } }
/** * Determine whether the Class identified by the supplied name is present and can be loaded. * 判断由提供的类名(类的全限定名)标识的类是否存在并可以加载 * 如果类或其中一个依赖关系不存在或无法加载,则返回false * @param className 要检查的类的名称 * @param classLoader 加载该类使用的类加载器 * 可以是 null, 表明使用默认的类加载器 * @return 指定的类是否存在 */ public static boolean isPresent(String className, ClassLoader classLoader) { try { forName(className, classLoader); return true; } catch (Throwable ex) { // Class or one of its dependencies is not present... return false; } }
可见,以上都是用了
Class.forName来完成。
Class.forName在没有找到该类时抛出
ClassNotFoundException异常。
我们所需要做的仅仅是屏蔽该异常,并设置一个表示当前类不存在的标识。
那么问题来了,我们都知道
Class.forName会导致我们加载的类去执行静态代码块(当然也可以设置不进行初始化),以及静态属性的初始化。在JVM中对应于
invokeSpecial <cint>。
但是
在java中如何判断一个类是否存在这一简单问题似乎没有必要这样做。
那么如下的代码似乎更符合我们的要求吧?
public static boolean isPresent(String name) { try { Thread.currentThread().getContextClassLoader().loadClass(name); return true; } catch (ClassNotFoundException e) { return false; } }
以上的
loadClass(String name)方法会去调用该类中的protected方法
java.lang.ClassLoader#loadClass(java.lang.String, boolean)
public Class<?> loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); }
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }
resolve参数表示是否进行链接。
两者的区别见:
http://blog.csdn.net/x_iya/article/details/73199280
相关文章推荐
- VBS中如何判断一个引用对象是否存在?
- ORACEL如何判断一个表中某列是否存在
- 如何判断数据库中是否存在一个数据表
- bash如何判断一个文件是否存在
- [VB.NET]如何在一个窗体M中判断另一个窗体N中是否存在一个名称为A的事件?
- 微软面试(or电面)试题——如何判断一个单链表是否存在回路
- 如何使用JQuery去判断一个元素(对象)是否存在
- 如何用js判断document里的一个对象是否存在?或是是否有效
- makefile中如何判断一个文件是否存在
- JavaScript 里如何判断一个字符串里是否存在某个字符串?(支持中文)
- 如何判断一个图中是否存在回路
- java如何做到判断一个字符串是否是数字
- jquery和js如何判断一个对象是否存在
- Sql : 如何判断一个表中,是否存在一个ID,如果存在不处理,如果不存在
- 如何判断一个文件是否存在
- sql 如何判断一个表是否存在
- javascript中如何判断一个元素在页面中是否存在(转)
- [SQL,Java]判断某一个已知表名的表是否在数据库中存在的方法
- unix下如何判断一个文件夹是否存在?
- 如何判断一个已知的表中是否存在某个字段,如果不存在就创建它.