问题:这保证有效吗?
答:视情况而定。我想指出一个潜在的问题。
“真正的”@SafeVarargs 注释是用 RetentionPolicy.RUNTIME 声明的(见这里)。其原因(与具有 RetentionPolicy.SOURCE 的 @Override 相比)可能是允许编译器在调用站点检查它。然而,
- 如果您的 SafeVarargs 注释版本是使用 RetentionPolicy.RUNTIME 声明的
- 并且使用它的代码使用 JRE 6 运行(不包含此注释)
- 并且您的 SafeVarargs 注释版本位于类路径中
那么任何在运行时使用反射来获取方法注释的代码(例如 Spring 框架)都会因 SecurityException 而失败,因为注释的包名以“java”开头。(参见来自 Sun JRE 1.6.0_31 的 ClassLoader.preDefineClass() 方法和下面的 stacttrace 的相关代码)。
如果注释在编译时位于类路径上,但不在运行时(maven 中的“提供”范围),则不会引发异常(至少对于 Sun JRE)。
最好的解决方案是使用一些 Maven 工件,例如 java.lang.java7-annotations,并在“提供”范围内使用它。我在这里找到了一些东西(工件:com.google.backport.safevarargs),但它不在中央仓库中。
if ((name != null) && name.startsWith("java.")) {
throw new SecurityException("禁止的包名:" +
name.substring(0, name.lastIndexOf('.')));
}
线程“主”java.lang.SecurityException 中的异常:禁止的包名称:java.lang
在 java.lang.ClassLoader.preDefineClass(ClassLoader.java:479)
在 java.lang.ClassLoader.defineClassCond(ClassLoader.java:625)
在 java.lang.ClassLoader.defineClass(ClassLoader.java:615)
在 java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
在 java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
在 java.net.URLClassLoader.access$000(URLClassLoader.java:58)
在 java.net.URLClassLoader$1.run(URLClassLoader.java:197)
在 java.security.AccessController.doPrivileged(本机方法)
在 java.net.URLClassLoader.findClass(URLClassLoader.java:190)
在 java.lang.ClassLoader.loadClass(ClassLoader.java:306)
在 sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
在 java.lang.ClassLoader.loadClass(ClassLoader.java:247)