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;
}