问题
I have a question regarding to the andriod @IntDef
Annotation. I know
that in its basic usage, it should replace the enum
. But what if
I have a parameterized enum with multiple hardwired values for example
public enum MyEnum {
YES(true, 1),
NO(false, 0);
private boolean boolState;
private boolean intState;
MyEnum(boolean boolState, int intState) {
this.boolState = boolState;
this.intState = intState;
}
public boolean getBoolState() {
return boolState;
}
public int getIntState() {
return intState;
}
}
How would this be replaced by an Enumerated Annotation in Android?
Is it even suggestive to do something like that in this case? I searched everywhere, but I haven't found any answer for that.
Thank you in advance!
回答1:
I don't think you would be able to find anything because:
IntDef is a way of replacing an integer enum where there's a parameter that should only accept explicit int values.
you can read more about it here. Enumerated annotations are for simple types, you could use it for strings also StringDef
. Use enum when you need its features. Don't avoid it strictly. For your case I think creating class instead of enum would look like this:
public class MyEnum {
public static final MyEnum YES = new MyEnum(true, 1);
public static final MyEnum NO = new MyEnum(false, 0);
private boolean boolState;
private int intState;
MyEnum(boolean boolState, int intState) {
this.boolState = boolState;
this.intState = intState;
}
public boolean getBoolState() {
return boolState;
}
public int getIntState() {
return intState;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyEnum myEnum = (MyEnum) o;
return boolState == myEnum.boolState && intState == myEnum.intState;
}
}
and you could use constants in your code. But if using enums you will have type checking (you'll be able to accept only listed values) and method overloading (every enum constant can have its own implementation of a method). If you want to use less space and that is the only reason why you want to avoid using enum I would suggest you that it's not worth it.
回答2:
I follow a rule with enums in Android development:
- if it has no params, use an intdef/stringdef,
- if it has params, use an enum
If there is a way around using an enum, I'll certainly consider it where it doesn't undermine the code.
A lot was made from the video Colt Mcanlis posted: https://www.youtube.com/watch?v=Hzs6OBcvNQE&feature=youtu.be
however it had some fairly shaky numbers in it as pointed out by Jake Wharton: https://plus.google.com/+JakeWharton/posts/bTtjuFia5wm
The main drawback of enums is that they use more memory than constants would, but if that enum aids in better code, I say use it rather than micro-optimise. Just don't go overboard using them and be aware of their footprint.
回答3:
I'm coming late, but anyways, since intdef ins an annotation, you can create an annotation using a custom class and then use it in the same way. given the fact an annotation needs primitives, you'll have to pass an interface as the annotation class type, and use subclasses as the value array.
example:
public interface GenericContainer<T, X> {
public T getValueOne();
public X getValueTwo();
}
then an implementation for true/1
public class TrueContainer implements GenericContainer<Boolean, Integer> {
@Override
public Boolean getValueOne() {
return true;
}
@Override
public Integer getValueTwo() {
return 1;
}
}
and other for false/0
public class FalseContainer implements GenericContainer<Boolean, Integer> {
@Override
public Boolean getValueOne() {
return false;
}
@Override
public Integer getValueTwo() {
return 0;
}
}
finally, use them:
@Retention(RetentionPolicy.SOURCE)
@GenericDef({TrueContainer.class, FalseContainer.class})
public @interface genericTest{}
boolean test = isTest(new FalseContainer());
来源:https://stackoverflow.com/questions/42512818/convert-parametized-enum-to-enumerated-annotation-in-android