Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为@Annotation枚举赋值_Java_Enums_Annotations - Fatal编程技术网

Java 为@Annotation枚举赋值

Java 为@Annotation枚举赋值,java,enums,annotations,Java,Enums,Annotations,我创造 enum Restrictions{ none, enumeration, fractionDigits, length, maxExclusive, maxInclusive, maxLength, minExclusive, minInclusive, minLength, pattern, totalDigits, whiteSpace; public Restrictions setValue(int value){

我创造

enum Restrictions{
  none,
  enumeration,
  fractionDigits,
  length,
  maxExclusive,
  maxInclusive,
  maxLength,
  minExclusive,
  minInclusive,
  minLength,
  pattern,
  totalDigits,
  whiteSpace;

  public Restrictions setValue(int value){
    this.value = value;
    return this;
  }
  public int value;
}
所以我可以很高兴地做这样的事情,这是完全合法的语法

Restrictions r1 =
  Restrictions.maxLength.setValue(64);
原因是,我正在使用enum来限制可以使用的限制类型,并能够为该限制指定一个值

然而,我的实际动机是在@annotation中使用该限制

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
public @interface Presentable {
  Restrictions[] restrictions() default Restrictions.none;
}
因此,我打算这样做:

@Presentable(restrictions=Restrictions.maxLength.setValue(64))
public String userName;
编译器发出嘎嘎声

The value for annotation enum attribute must be an enum constant expression.

是否有一种方法可以实现我希望实现的目标

您可以实现您想要的目标,但不能直接使用enum

如果使用私有构造函数和静态常量字段将限制设置为常规类,则可以使用方法链接流畅地创建新实例:

enum RestrictionType
{
   none,
   enumeration,
   maximumLength, 
   // ... etc.
}

class Restriction {
  static public final Restriction none = new Restriction(RestrictionType.none);
  static public final Restriction enumeration = new Restriction(RestrictionType.enumeration);
  static public final Restriction maximumLength = new Restriction(RestrictionType.maximumLength);

  ... etc

  RestrictionType type;
  int value;

  private Restriction(RestrictionType type)
  {
    this(type, 0);
  }
  private Restriction(RestrictionType type, int value)
  {
     this.type = type;
     this.value = value; // you don't really need
  }

  static public Restriction setValue(int value)
  {
      return new Restriction(type, value);
  }
}
然后将其完全用作原始代码:

@Presentable(restrictions=Restrictions.maxLength.setValue(64))
public String userName;

然而,我担心的是这里缺少OO——如果限制有不同的行为或定义所需的数据,那么最终会将所有内容都集中到限制类中。最好为不同的限制类型创建子类。

编译错误的一部分,假设您能够完全做到这一点。那么你不认为在其他领域应用类似的注释会毁掉第一个吗

我是说,

@Presentable(restrictions=Restrictions.maxLength.setValue(64))
public String userName;
@Presentable(restrictions=Restrictions.maxLength.setValue(32))
public String password;
同一个实例现在将有一个不同的值,即32。所以,我相信64号将会丢失。在这种情况下,它们是在运行时顺序处理的,当我们将值更改为32时,64已经处理了一个。然后我想,我们可以将
mdma
给出的示例中的
setter
方法更改为如下内容

 static public Restriction setValue(int value) {    
      this.value = value;
      return this;
  }

您可以这样做:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

class Person {    
    @Presentable({
        @Restriction(type = RestrictionType.LENGTH, value = 5),
        @Restriction(type = RestrictionType.FRACTION_DIGIT, value = 2)
    })
    public String name;
}

enum RestrictionType {
    NONE, LENGTH, FRACTION_DIGIT;
}

@Retention(RetentionPolicy.RUNTIME)
@interface Restriction {
    //The below fixes the compile error by changing type from String to RestrictionType
    RestrictionType type() default RestrictionType.NONE;
    int value() default 0;
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@interface Presentable {
  Restriction[] value();
}

我选择阿宾的作为我的问题的答案,因为它是最全面的,而且在我尝试的时候它是有效的。然而,我在这里以回答我自己问题的形式记录了我的实际行动

重新命名Abhin的术语,这将是我应用它的方式(类似于Abhin的示例):

我觉得这太冗长了。我甚至可以把它缩短为:

@Presentable({
@R(r=R.FractionDigits, v="1"),
@R(r=R.Length, v="10"),
    .....
})
这可能太让人费解了,而且仍然无法赘述。我需要的是程序员能够快速而全面地指定的东西:

@Presentable(sequence = 11, maxLen=64, readOnly=true)
因此,我决定使用又快又脏的:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
public @interface Presentable {
    int sequence();
    String caption() default "";
    int fractionDigits() default -1;
    int length() default -1;
    int maxLen() default -1;
    int minLen() default -1;
    int totalDigits() default -1;
    float maxVal() default -1;
    float minVal() default -1;
    String pattern() default "";
    String whiteSpace() default "";
    boolean readOnly() default false;
    boolean multiValue() default false;
    boolean hidden() default false;
    boolean isTest() default true;
}

无论如何,我把阿宾的答案藏在我的秘密里,以备将来使用

您似乎重新发明了
javax.validation
(JSR303)。你考虑过用它吗?你看过它的API/IMPL了吗?Hibernate不能与GAE一起工作,是吗?那是Hibernate验证程序,而不是Hibernate本身。这应该适用于所有地方。(如果没有,您基于注释的版本也不会)您不认为每次调用set方法时都会创建一个新实例吗?public@interface Presentable{Restriction[]restrictions()default Restriction.none;}会导致编译器发出嘎嘎声只允许使用基元类型、字符串、类、注释或枚举或其1维数组。“@h2g2java生成
限制
注释类型。@Adeel-是这将为每个注释创建一个新实例。注释具有状态,因此需要单独的实例。你怎么能不创建一个新的实例就完成它呢?我同意它有状态。事实上,这是一个更好的方法。一开始我就看不到这一点,但我的想法是一样的+1正确!枚举是常量对象(编译为最终类),因此每个枚举值都是一个单例。枚举永远不应该是可变对象,IMHO。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
public @interface Presentable {
    int sequence();
    String caption() default "";
    int fractionDigits() default -1;
    int length() default -1;
    int maxLen() default -1;
    int minLen() default -1;
    int totalDigits() default -1;
    float maxVal() default -1;
    float minVal() default -1;
    String pattern() default "";
    String whiteSpace() default "";
    boolean readOnly() default false;
    boolean multiValue() default false;
    boolean hidden() default false;
    boolean isTest() default true;
}