我有一个名为getInfo()
的方法。它只有一个参数,但参数只能有两种可能的类型Exception
或自定义类CLAZZ_A
。因此,当我定义此方法getInfo()
时,我想将其参数类型限制为两者。我能做什么?我相信Java泛型类型可能有用,但我不知道该怎么做。
答案 0 :(得分:0)
也许只是超载:
getInfo(Exception e){}
getInfo(MyClass mc){}
通过这种方式,您可以在编译时知道您的参数是什么,并保证它是两个可接受的参数之一。如果行为足够相似,你可以通过强制转换从另一个中调用一个。
如果这没有吸引力,请考虑让对象扩展Exception(如果相关),那样getInfo(Exception e){}
就足够了。
答案 1 :(得分:0)
在泛型中,类型参数可以具有以下形式的多个边界:<T extends B1 & B2 & B3 ... >
。因此,如果您想将方法的参数限制为2种类型,请尝试这样的方法。 (CLAZZ_A必须是这个工作的接口)
class SomeClass {
<T extends Exception & CLAZZ_A> void doSomething(T t) {
// ...
}
}
答案 2 :(得分:0)
如果您不喜欢重载,可以创建类似Try
monad的内容。这种单子通常代表某种事物的成功结果或某种例外所描述的失败。可能这与你的情景很接近。
// Represents either some successful result of type T or failure
public class Try<T> {
final T value;
final Exception ex;
private Try(T value, Exception ex) {
this.value = value;
this.ex = ex;
}
// Construct Try with normal value
public static <T> Try<T> of(T value) {
return new Try<>(value, null);
}
// Construct an exceptional Try with given exception
public static <T> Try<T> exceptional(Exception ex) {
return new Try<>(null, ex);
}
// Run given Callable and construct either successful Try or exceptional
// based on result
public static <T> Try<T> run(Callable<T> c) {
try {
return of(c.call());
}
catch(Exception ex) {
return exceptional(ex);
}
}
// Return true if this Try represents successful result
public boolean isSuccess() {
return ex == null;
}
// return stored value or throw an exception if this Try is exceptional
public T get() throws Exception {
if(ex != null) throw ex;
return value;
}
// Returns result of this Try or supplied default result if this Try
// is exceptional
public T getOrDefault(T defaultValue) {
if(ex != null) return defaultValue;
return value;
}
// Returns exception of exceptional Try or null for successful Try
public Exception getException() {
return ex;
}
}
这只是一个粗略的草图。您可以添加其他便捷方法或使用一些提供类似类的ready库。
现在你可以这样声明你的方法:
void getInfo(Try<CLAZZ_A> value) { ... }
并像这样使用:
getInfo(Try.of(new CLAZZ_A()));
或者
getInfo(Try.exceptional(new Exception()));
或(使用Java-8语法)
getInfo(Try.run(() -> fetchTheCLAZZ_A()));
现在你有了严格的类型控制:你只能传递Try
对象,它可以包含CLASS_A
个对象或Exception
。使用Try
方法可以方便地处理getInfo
方法中的两种情况,并且不需要任何类型转换。