英文:
How can I supply a symbol to a Java annotation?
问题
以下是翻译好的内容:
看起来我的误解导致了我提出这个问题。请帮我梳理一下。JLS 9.6.1规定了“类或类的调用(§4.5)”作为注解类型,chrylis -cautiouslyoptimistic指出了这一点。
我们都同意静态导入是一个常量(好吧,假装我没有说过这句话:当然不是真的 https://stackoverflow.com/a/9083023/1236128)
import static path.to.someFunction
我像这样创建了一个注解:
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface Testing {
Class<? extends Function> symbol();
}
鉴于一个静态函数(即使将其声明为final也不能使someFunction
在Java中符合常量的定义,这让我困惑):
public static Function<Long, Long> someFunction = a -> b;
请原谅我(我意识到函数本身与其应用之间有区别):
public static Function<Long, Long> someFunction = a -> 2L;
我像这样创建了一个单元测试(假设前面提到的静态导入):
@Test
@Testing(symbol = someFunction)
void someFunctionTest() {
....
}
除了我的错误,有人认识到这在编译时会有多么有用吗?我可以对所有标有@Tested
的函数使用反射,以查看是否确实存在某个地方对其进行了测试(基于@Testing
注解)。
有趣的是,我给注解提供了一个常量,但IntelliJ报错:
属性值必须是常量。
这是怎么回事?注解机制是试图执行该函数,还是会将其视为高阶函数?
英文:
It looks like my misconceptions have led me to this question. Please help me sort them out. JLS 9.6.1 states that "Class or an invocation of Class (§4.5)" is covered as an annotation type, chrylis -cautiouslyoptimistic pointed out.
We all agree that a static import is a constant (well, pretend I did not make that statement: It is of course not true https://stackoverflow.com/a/9083023/1236128)
import static path.to.someFunction
I create an annotation like this
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface Testing {
Class<? extends Function> symbol();
}
Given a static function (even declaring this final does not make someFunction
constant by definition in Java, which is throwing me off):
public static Function<Long, Long> someFunction = a -> b;
Excuse me (I realize there is a difference between the function itself and its application),
public static Function<Long, Long> someFunction = a -> 2L;
I create a unit test like this (assuming the aforementioned static import):
@Test
@Testing(symbol = someFunction)
void someFunctionTest() {
....
}
Aside from my mistakes, does anybody recognize how useful this would be at compile time? I could use reflection on all functions marked with say @Tested
to see whether there is indeed a test for it somewhere (on the basis of the @Testing
annotation).
The funny thing is, I am supplying the annotation with a constant, but that is the complaint given by IntelliJ:
> Attribute value must be [a] constant.
What's up with that? Is the annotation mechanism trying to execute the function, or will it accept it as a higher order function?
答案1
得分: 1
> 我们都同意静态导入是一个常量。
不,我们并不同意。
静态导入除了使字段/方法/...能够通过简单名称访问外,什么都不做,而不必使用完全限定的名称。
那个简单的名称可能是对常量字段的引用,也可能是对其他内容的引用。
你已经将 someFunction
定义为
public static Function<Long, Long> someFunction = a -> b;
根据Java语言的规则,这不是 一个“常量表达式”(我强调):
> 常量表达式是表示原始类型或String值的表达式[...]
显然,Function
既不是原始值也不是 String
。
另外,你已经将 symbol
定义为接受 Class<? extends Function>
,这意味着你需要为它分配一个实现了 Function
的类。someFunction
不是一个 Class
,它是一个实际实现了 Function
的对象。
英文:
> We all agree that a static import is a constant.
No, we don't.
A static import does nothing other than making a field/method/... accessible via a simple name as opposed to having to use the fully qualified name.
That simple name might be a reference to a constant field or it might be a reference to something else.
You've defined someFunction
as
public static Function<Long, Long> someFunction = a -> b;
According to the rules of the Java language that is not a "constant expression" (emphasis mine):
> A constant expression is an expression denoting a value of primitive type or a String [...]
Obviously a Function
is neither a primitive value nor a String
.
Additionally you've defined the symbol
to take a Class<? extends Function>
, which means you need to assign it a class that implements Function
. someFunction
is not a Class
, it's an actual object that happens to implement Function
.
答案2
得分: 1
总体答案是不可以的,你不能这样做。而且你的代码由于多种原因无法工作:
someFunction
不是编译时常量someFunction
不是Class<? extends Function>
,而symbol
需要的是这个类型- 实际类型
Function<?,?>
在注解中不被支持作为属性类型。
英文:
The overall answer is no, you cannot do this. And your code does not work for a multitude of reasons:
someFunction
is not a compile time constantsomeFunction
is not aClass<? extends Function>
assymbol
expects- the actual type
Function<?,?>
is not supported as an attribute type in annotations.
答案3
得分: 0
你不能按原样执行此操作。JLS 9.6.1:
在注解类型中声明的方法的返回类型必须是以下类型之一,否则会导致编译时错误:
- 原始类型
- String
- Class 或 Class 的调用(§4.5)
- 枚举类型
- 注解类型
- 其组件类型为前述类型之一的数组类型(§10.1)。
英文:
You can't do it as-is. JLS 9.6.1:
> The return type of a method declared in an annotation type must be one of the following, or a compile-time error occurs:
>
> - A primitive type
> - String
> - Class or an invocation of Class (§4.5)
> - An enum type
> - An annotation type
> - An array type whose component type is one of the preceding types (§10.1).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论