如何在方法中使用泛型参数将参数类型限制为某些特定的类类型?

时间:2015-09-25 03:00:22

标签: java generics

我有一个名为getInfo()的方法。它只有一个参数,但参数只能有两种可能的类型Exception或自定义类CLAZZ_A。因此,当我定义此方法getInfo()时,我想将其参数类型限制为两者。我能做什么?我相信Java泛型类型可能有用,但我不知道该怎么做。

3 个答案:

答案 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方法中的两种情况,并且不需要任何类型转换。