请考虑以下事项:
public interface MyFilter {
@FilterAttribute
String getAttribute();
}
@Retention(RUNTIME)
@Target(METHOD)
@Implementor(AutoEnumFilterAttribute.class)
public @interface FilterAttribute{
}
public enum MyEnumType2Filter implements MyFilter{
TYPE0,
TYPE1;
}
public enum MyEnumType2Filter implements MyFilter{
TYPE20,
TYPE21;
}
还有更多......
MyFilter.getAttribute()实现在所有情况下看起来都是这样的。
...
public String getAttribute() {
return "attribute."+name().toLowerCase()+".filter";
}
...
我们可以看到,在实现此接口的每个枚举中都有不必要的重复实现。 当然,我可以有一个单独的助手类,我做这样的事情
public final class MyFilterHelp {
public static String getAttribute(MyFilter filter) {
//check that it is an enum then,
return "attribute."+filter.name().toLowerCase()+".filter";
}
}
or
public enum MyEnum implements MyFilter {
TYPE20;
private String attribute;
private MyEnum () {
this.attribute = "attribute."+name().toLowerCase()+".filter";
}
public Strign getAttribute() {
return this.attribute;
}
}
但是这个第一个选项将属性与枚举分开,而section选项仍然需要为实现此接口的每个枚举实现。
我的愿景是。
public class AutoEnumFilterAttribute<MyFilter> {
public String getAttribute(MyFilter filter) {
//check that it is an enum then,
return "attribute."+filter.name().toLowerCase()+".filter";
}
}
并且通常使用我的枚举过滤器(AutoEnumFilterAttribute在某种程度上像代理一样):
MyFilter filter = ...
String attribute = filter.getAttribute();
我猜测我可以通过&#34;注射&#34;在编译期间实现此接口的每个枚举中实现MyFilter.getAttribute()。
关于如何解决这个问题的任何想法? 考虑jdk7或以下。
正如所回答的那样,可以使用java8 default method
来做到这一点答案 0 :(得分:1)
如果您正在使用 Java 8 ,则可以在界面中使用default method。如果你将它与指定枚举方法name()
结合起来,那么你就会非常接近你想要的东西。
interface MyFilter {
default String getAttribute() {
return "attribute."+name().toLowerCase()+".filter";
} // you no longer have to implement this in your enums
String name(); // you need to specify this method here in order to use it in the default method
}
由于每个枚举都已经实现了name(),因此对现有类没有任何惩罚(即不进行重构),并且您将以简洁的方式获得所需的API方法。
如果您正在使用旧版本的Java ,那么您的解决方案将会相当复杂。您可以考虑撰写Annotation Preprocessor。我自己没有使用它们,但我曾经看过一个演示并且已经阅读了一些它。请记住,我可能没有把一切都弄好。
一个非常简短的总结是,您可以使用自定义注释标记类,并让Annotation预处理器选择这些类并为它们自动生成一些代码。最好的部分是编译器在编译时会知道这一点,因为您可以将预处理器配置为在编译器之前运行。因此,编译器不会忽视您在“预编译”时添加的任何方法。
所以我的想法是创造这样的东西:
interface MyFilter {
String getAttribute();
}
@AddGetAttribute
enum MyEnumType2Filter implements MyFilter {
TYPE20, TYPE21
}
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.CLASS)
@interface AddGetAttribute {}
@SupportedAnnotationTypes("com.blagae.AddGetAttribute")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class AttributeProcessor extends AbstractProcessor {
public AttributeProcessor() {
super();
}
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
/* this method should let you add the source code for your enums
see links below for some basic examples
you will need to try and add a method to your existing class,
instead of creating a new class file as these links do.
*/
return false;
}
}
我承诺的链接: