我试图在注释中创建一些信息树结构。经过一些尝试和帮助(请参阅java注释中的类型层次结构),我转向了以下模型。
@interface Node {
LogicalExpression logicalExpression() default LogicalExpression.AND;
Attribute[] attributes() default {};
Node[] nodes() default {};
}
该节点应允许我定义一级条件树。LogicalPression中的值定义子节点(属性和其他节点)之间的关系。问题是注释不允许递归依赖:
Cycle detected: the annotation type Node cannot contain attributes of the annotation type itself
即使我在Node和NodeList包含节点列表中添加了一些NodeList注释,循环依赖也会再次被识别。
@interface NodeList {
Node[] nodes();
}
@interface Node {
LogicalExpression logicalExpression() default LogicalExpression.AND;
Attribute[] attributes() default {};
NodeList nodes() default EmptyList;
}
循环注释定义有什么解决方案吗?
我知道我有点晚了,但今天我不得不解决同一个问题,我发现这个问题没有真正的解决方案或变通方法。
但是,我设法使用以下结构“代理”递归:
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Expression
{
Node value();
SubExpression[] subExpressions() default {};
}
@Retention(RetentionPolicy.RUNTIME)
@interface SubExpression
{
String id();
String operator();
Node[] nodes();
}
@Retention(RetentionPolicy.RUNTIME)
@interface Node
{
String subExpression() default "";
String name() default "";
String value() default "";
}
@Expression(
value = @Node(subExpression = "1"),
subExpressions = {
@SubExpression(id = "1", operator = "AND",
nodes = {
@Node(name = "responsible", value = "foo"),
@Node(subExpression = "2")
}),
@SubExpression(id = "2", operator = "OR",
nodes = {
@Node(name = "status", value = "closed"),
@Node(name = "visibility", value = "public")
}),
})
public class TestAnnotationRecursion
{
public static void main(String[] args)
{
Expression expression = TestAnnotationRecursion.class.getAnnotation(Expression.class);
Map<String, SubExpression> subExpressionMap = Arrays.stream(expression.subExpressions())
.collect(Collectors.toMap(x -> x.id(), x -> x));
String result = parseNode(expression.value(), subExpressionMap);
System.out.println(result);
}
public static String parseNode(Node node, Map<String, SubExpression> subExpressionMap)
{
String subExpressionId = node.subExpression();
if(subExpressionId.isEmpty())
{
return node.name() + " = '" + node.value() + "'";
}
SubExpression subExpression = subExpressionMap.get(subExpressionId);
return Arrays.stream(subExpression.nodes())
.map(n -> parseNode(n, subExpressionMap))
.collect(Collectors.joining(" " + subExpression.operator() + " ", "(", ")"));
}
}
评估结果如下:
(responsible = 'foo' AND (status = 'closed' OR visibility = 'public'))
虽然它的易读性值得怀疑,但我认为这是我们在不允许显式递归时可以实现的最佳妥协。
由于上述Java中的限制,您无法定义无限递归定义。但是您可以支持一些固定深度的结构,这感觉像递归结构(直到达到深度限制为止)
这是深度3的布尔表达式语言的示例:
public @interface Expression {
public Term value () default @Term;
public And and () default @And;
public Or or () default @Or;
}
定义每个级别的“和”操作:
public @interface And {
public boolean not () default false;
public Term[] value () default {};
public Or1[] or1 () default {};
public Or2[] or2 () default {};
public And1[] and1 () default {};
public And2[] and2 () default {};
}
public @interface And1 {
public boolean not () default false;
public Term[] value () default {};
public Or2[] or2 () default {};
public And2[] and2 () default {};
}
public @interface And2 {
public boolean not () default false;
public Term[] value () default {};
}
定义每个级别的“或”操作:
public @interface Or {
public boolean not () default false;
public Term[] value() default {};
public Or1[] or1 () default {};
public Or2[] or2 () default {};
public And1[] and1 () default {};
public And2[] and2 () default {};
}
public @interface Or1 {
public boolean not () default false;
public Term[] value () default {};
public Or2[] or2 () default {};
public And2[] and2 () default {};
}
public @interface Or2 {
public boolean not () default false;
public Term[] value () default {};
}
现在我们可以这样使用它:
@Expression(@Term("a"))
class A{}
// a or b
@Expression(or=@Or({@Term("a"), @Term("b")}))
class B{}
// a or (not(b and c))
@Expression(or=@Or(
value=@Term("a"),
and1=@And1(not=true, value={
@Term("b"),
@Term("b")
})
))
class B{}
正如您所看到的,这个想法是在每次添加嵌套表达式时增加运算符注释的索引。
这是因为这个错误。
注释的继承性、多态性、循环检测的局限性。。。线程讨论它。
您可以创建如下内容
@interface NodeInfo {
LogicalExpression logicalExpression() default LogicalExpression.AND;
Attribute[] attributes() default {};
}
@interface Node {
NodeInfo[] nodes() default {};
}
我实现了一个非常简单的递归方法,将两个数相乘在一起。我很难理解递归的基本知识。 有没有人能向我解释(如果可能的话,逐行解释)这段代码是如何工作的?我尤其感到困惑的是,基大小写被写为返回0,而实际上返回的是实际的乘法。 谢谢你的帮助
问题内容: 丈夫.java 妻子.java Service.java 当我使用spring数据jpa从数据库中查询丈夫时,结果发生无限递归,参见下图。使用@OneToOne注释时出了什么问题?有人可以给我一些建议吗?或者我以错误的方式使用了注释。 图片 问题答案: 这是一个已知问题,当您具有双向关系时,杰克逊将尝试从另一侧序列化一侧的每个引用,以便逻辑上具有无限递归。 解决方案:有很多解决方案,可
问题内容: 请分步说明递归; 问题答案: 如果您使用的是IDE,则可以使用调试器,亲眼看看发生了什么。 无论如何,让我们尝试一下,当调用递归方法时会发生什么:您使用8()调用该方法: -> 8 ->以8/2 = 4再次调用方法 -> 4 >以4/2 = 2再次调用方法 -> 2 >用2/2 = 1再次调用方法 ->继续上一个通话,() >用2/2 = 1再次调用方法 ->继续上一个通话,() 方法
假设我有一个带有属性的注释: 我想创建一个包含多个元注释的复合注释,包括一个带有属性的注释 有没有一种方法可以将复合注释的属性传递给其中一个元注释? 例如,类似这样的东西: 这相当于,但比 谢谢! PS为我对示例注释的错误选择表示歉意-我没有javax。注射@记住命名注释,只是一些具有属性的任意注释。 谢谢大家的回答/评论。 这显然是不可能的。然而,碰巧我的案例有一个简单的解决方法,我将与大家分享
我有几个项目,没有一个是在Maven框架下。 但是我在项目依赖领域面临一个问题。 让我们用一个非常简单的例子来假设; 我理解这种情况很正常,因为不在类路径上。虽然,我说的是一个更复杂的层次树,我不希望高层项目在他下面添加所有的子依赖树。 提前感谢!
注释是对程序语言的说明,有助于开发者和用户之间的交流,方便理解程序。 注释不是编程语句,因此被编译器忽略。 Java 支持以下三种注释方式: 1)单行注释 以双斜杠“//”标识,只能注释一行内容,用在注释信息内容少的地方。打开 Eclipse,在 Java 代码中使用单行注释,如图 1 所示。 图 1 单行注释 2)多行注释 包含在“/*”和“*/”之间,能注释很多行的内容。为了可读性比较好,一