gpt4 book ai didi

java - @SafeVarargs 和 Java 6 的互操作性

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:34:32 25 4
gpt4 key购买 nike

我的 API 中有一个带有通用可变参数的方法。我希望我的 API 与 Java 6 源代码和二进制兼容,但如果 Java 7 API 使用者不会遭受不必要的 “varargs” 警告,那就太好了。

我能想到的一个技巧是将我自己的 java.lang.SafeVarargs 注释添加到我的 API 并将其与我的可交付成果一起发送。结果:

  • Java 6 编译器无法识别此注解并忽略它。
  • Java 7 编译器会识别此注释,并且可能(?)首先从 JDK 类加载注释,因此它们不会再产生烦人的警告。

除了许可方面的问题,这能保证有效吗?它似乎适用于 javac。或者是否存在从 JDK 重新定义注释的配置会在调用站点产生不良副作用?或者有其他方法可以解决这个 Java 6/7 互操作性问题吗?

相关问题:

最佳答案

问题:这能保证有效吗?

答案:视情况而定。我想指出一个潜在的问题。

“真正的”@SafeVarargs 注释是用 RetentionPolicy.RUNTIME 声明的(参见 here )。这样做的原因(与具有 RetentionPolicy.SOURCE 的 @Override 相反)可能是为了允许编译器在调用站点检查它。然而,

  • 如果您的 SafeVarargs 注释版本是使用 RetentionPolicy.RUNTIME 声明的
  • 并且使用它的代码是使用 JRE 6 运行的(不包含此注释)
  • 并且您的 SafeVarargs 注释版本在类路径中

那么任何使用反射在运行时获取方法注释的代码(例如 Spring 框架)都会因 SecurityException 而失败,因为注释的包名称以“java”开头。 (请参阅 ClassLoader.preDefineClass() 方法的相关代码和下面的 statrace,均来自 Sun JRE 1.6.0_31)。

如果注释在编译时位于类路径上但在运行时不在(maven 中的“提供”范围),则不会抛出异常(至少对于 Sun JRE)。

最好的解决方案是拥有一些 Maven 工件,如 java.lang.java7-annotations,并在“提供”的范围内使用它。我发现了一些东西 here (工件:com.google.backport.safevarargs)但它不在中央仓库中。


if ((name != null) && name.startsWith("java.")) {    throw new SecurityException("Prohibited package name: " +                                 name.substring(0, name.lastIndexOf('.')));}
Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.lang    at java.lang.ClassLoader.preDefineClass(ClassLoader.java:479)    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:625)    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)    at java.security.AccessController.doPrivileged(Native Method)    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

关于java - @SafeVarargs 和 Java 6 的互操作性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16366780/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com