在Java中,是否可以指定一个通用方法来匹配包含除枚举之外的任何对象的列表?
public class Foo {
public enum MyEnum {
ENUM_VALUE
}
public static <T ...generics magic...> void bar(List<T> argument) {
// .. code
}
public static void test() {
Foo.bar(Arrays.asList(new Object())); // OK
Foo.bar(Arrays.asList(new Exception())); // Still OK
Foo.bar(Arrays.asList(MyEnum.ENUM_VALUE)); // Compiler error, please?
}
}
public static <T> void bar(List<T> argument, Class<T> argumentType) { if (Enum.class.isAssignableFrom(argumentType)) { throw new IllegalArgumentException("Enums are disallowed."); } }
编辑:我对此感兴趣,因为我有一个允许消费者使用的API:
public&lt; T&gt; void setList(List&lt; T&gt; contents,boolean returnClones)
public&lt; T&gt; T get(int index)
当然,如果T是Enum,那么使用true指定returnClones是没有意义的 - 我们无法创建Enum的克隆。还有其他一些克隆不起作用的情况(例如,没有args构造函数不可用)。我正在努力使API尽可能健壮。
编辑#2:我知道枚举是不可变的;我正在寻找阻止调用者意外地为API指定无效参数的最佳方法。来电者永远不应该
Cloneable是一个很好的建议,但是接口的目的是不同的:“一个类实现了Cloneable接口,以向Object.clone()方法表明该方法制作字段是合法的 - 该类实例的for-field副本。“(Cloneable JavaDoc)。由于我们使用Dozer进行克隆而不是在源对象上调用clone(),我认为Cloneable最终会在这种情况下造成伤害而不仅仅是帮助。
答案 0 :(得分:1)
我做过一次重构,其中一个long参数更改为Object。解决方案是做类似的事情:
/**
* Not for enums.
* @param x use not an enum.
*/
@Deprecated
public <E extends Enum<E>> void f(E x) {
throw new IllegalArgumentException("...");
// Or better throw new UnsupportedOperationException("...");
}
public <T> void f(T x) {
...
}
在IDE的支持下,这样做很好。
最好在javadoc和异常消息中提及要使用的内容,其他f左右。