gpt4 book ai didi

java - 更换METHOD/FIELD/etc的兼容性风险是什么? TYPE_USE的目标

转载 作者:行者123 更新时间:2023-12-01 11:04:46 24 4
gpt4 key购买 nike

我有一个Java包,其中包含外部客户端使用的注释。该软件包出现在Java 8之前,因此从历史上看,这些注释的目标是ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE。现在,该软件包至少需要Java 8版本。语义上,包装中的注释适用于类型,例如注释方法时,注释有效地应用于方法返回类型。现在,客户也希望对通用类型参数进行注释(例如List<@MyAnnotation String>)。由于我们放弃了对Java 7及更低版本的支持,因此将注解目标设置为ElementType.TYPE_USE并减少歧义,删除现有目标似乎是很自然的。

问题是:用ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE替换TYPE_USE目标时,现有客户端是否存在兼容性风险?现有代码是否有可能停止编译?二进制兼容性如何?如果在运行时将更改之前编译的类文件与较新的注释包一起使用,是否会引起任何运行时问题?

如果这很重要,注释的保留策略是CLASS

最佳答案

在此更改过程中可能会出现许多源兼容性问题:

  • 不能再注释void返回类型的方法。 @MyAnnotation void method() {}可与ElementType.METHOD目标一起编译,但不可与TYPE_USE目标一起编译。
  • 在源代码中使用限定类型时,TYPE_USE批注必须出现在限定符之后。例如。 void method(@MyAnnotation OuterClass.InnerClass param) {}是具有ElementType.PARAMETER目标的有效代码,但在更改为void method(OuterClass.@MyAnnotation InnerClass param) {}后应更新为TYPE_USE
  • 应用于数组的注释将具有不同的含义。例如。在迁移@MyAnnotation String[] getData();注释方法getData之前,因此注释客户端可能会假定将注释应用于返回类型(字符串数组)。迁移后,相同的代码意味着注释将应用于数组组件(字符串)。这可能会导致行为更改,具体取决于注释的语义以及客户端如何对其进行处理。为了保留含义,客户应将这样的代码更新为String @MyAnnotation [] getData();
  • 这样的更改使Kotlin代码中的注释的所有用法无效。在Kotlin中,TYPE_USE注释和其他注释之间在语法上有严格的区别。例如。必须将PARAMETER注释用作fun(@MyAnnotation param : String) {...}。这对于TYPE_USE批注不正确,该批注必须用作fun(param : @MyAnnotation String) {...}。如果您的客户使用Kotlin,则必须修复每一个注释使用。
  • 此类更改不允许在Groovy代码中使用注释。目前,正如Groovy documentation所说,Groovy不支持Java 8中引入的TYPE_PARAMETER和TYPE_USE元素类型。如果您的客户使用Groovy,则他们将无法再使用您的注释包。

  • 但是,在运行时不会出现任何问题。由于注释的保留策略是 CLASS(不是 RUNTIME),而注释存在于类文件中,因此运行时将忽略它们。根本没有必要将注释包添加到类路径中。

    关于java - 更换METHOD/FIELD/etc的兼容性风险是什么? TYPE_USE的目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59978673/

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