Java将泛型类型与Void进行比较

时间:2014-12-03 10:11:18

标签: java generics types void

我有比较java泛型类型的问题,如果它是Void的类型。换句话说,我试图确保我的泛型类型T是否为Void。 我的示例实现:

public abstract class Request<T>{

     private T member;

     protected void comparing(){
         if(T instanceof Void) // this make error "Expression expected"
             runAnotherMethod();

         //if I type
         if(member instanceof Void) //Incovertible types; cannot cast T to java.lang.Void
             runAnotherMethod();
     }

     protected void runAnotherMethod(){...}
}

public class ParticularRequest extends Request<Void>{
}

我尝试通过instanceofClass<T>Class<Void>T.classVoid.class来比较ID。 但AndroidStudio在每个尝试过的案例中都显示错误:(

你可以帮我比较一下吗? 感谢。

6 个答案:

答案 0 :(得分:2)

使用java泛型时,您经常需要在构造函数中请求泛型类的类,以便您可以实际使用该类。我想,这是一个令人困惑的句子,所以请看下面的例子:

public abstract class Request<T> {

    private Class<T> clazz;

    // constructor that asks for the class of the generic type
    public Request(Class<T> clazz) {
        this.clazz = clazz;
    }

    // helper function involving the class of the generic type.
    // in this case we check if the generic type is of class java.lang.Void
    protected boolean isVoidRequest(){
        return clazz.equals(Void.class);
    }

    // functionality that depends on the generic type
    protected void comparing() {
        if (isVoidRequest()) {
            runAnotherMethod();
        }
    }

    // ...
}

当你继承子类时,你必须将泛型类的类传递给超级构造函数。

public class LongRequest extends Request<Long> {
    public LongRequest() {
        super(Long.class);
    }
}

public class VoidRequest extends Request<Void> {
    public VoidRequest() {
        super(Void.class);
    }
}

答案 1 :(得分:1)

您可以存储属于该类通用类型的private成员。

public abstract class Request<T> {

     private T memberOfGenericType;

     protected void comparing() {
         if (memberOfGenericType instanceof Sometype)
             runAnotherMethod();
     }

     protected void runAnotherMethod() { ... }

     public T getMemberOfGenericType() {
        return memberOfGenericType;
     }

     public void setMemberOfGenericType(T value) {
        this.memberOfGenericType = value;
     }
}

这样,在运行时,memberOfGenericType的类型为Sometype,您就可以编译 if语句。您还可以使用我添加的getter验证运行时memberOfGenericTypeSometype

无论如何,作为旁注,我会说不需要泛型类型,如果你不将它用作成员,方法或方法参数的类型然后你应该重新考虑你的设计。此外,特别是类型Void不可实例化,因此您无法为类成员传递有效实例,这会使if语句更多或更少。

答案 2 :(得分:0)

你不能那样使用T.你需要一些实例进行比较。例如某些成员或参数:

public abstract class Request<T> {
    T member;

     protected void comparing(T param){
         if(member instanceof Void)
             runAnotherMethod();

         if(param instanceof Void)
             runAnotherMethod();

     }

     protected void runAnotherMethod(){...}
}

答案 3 :(得分:0)

访问Guice使用的参数类的更好方法是使用以下事实:虽然泛型类不能访问自己的“类”参数,但其子类执行可以访问这些参数:请参阅https://stackoverflow.com/a/18610693/15472

如果你需要这个,可以使用Guice'TypeLiterals,或重新实现他们的逻辑。

答案 4 :(得分:0)

由于Java中没有Void类型实例的对象,因此您无法使用instanceof

null是唯一属于Void类型成员的值。那么也许你想要做的就是这个?:

 if (memberOfGenericType == null)
     runAnotherMethod();

关于类型Void

不能创建Void类型的对象,因为该类只有一个私有构造函数,并且永远不会从类中调用它。 Void通常用于以下情况:

  • 获取一个Class对象,该对象表示声明为返回void的方法的返回类型。
  • 作为占位符类型参数,当不打算使用该类型的字段和变量时。

答案 5 :(得分:0)

在运行时T编译为Object,实际的类未知。正如其他人所说,你应该维护一个参数化类型的实例,但这不是自动的:你需要实例化它,并且不能使用构造函数T()

同样java.lang.Void无法实例化,因此您应该使用其他类,例如自制的Void类。

尝试这样的事情:

public final class Void {}; // cannot use java.lang.Void, so create another class...

public abstract class Request<T> {
  protected abstract T member(); // A member would need to be initialized...

  protected void comparing(T param){
    if(member() instanceof Void) // Use our Void not java.lang.Void
      runAnotherMethod();

  }

  protected void runAnotherMethod(){...}
}

public class ParticularRequest extends Request<Void>{
  @Override
  protected Void member() { return new Void(); } // Could be optimized...
}

编辑:

我不明白,为什么你需要这个呢? 如果你有不同类型的孩子,那么你也可以有不同的实现。

这样的东西(类型和方法仅作为示例):

public abstract class Request<T> {
  protected abstract T method();
}

public class RequestInt extends Request<Integer> {
  @Override
  protected Integer method() {...}
}

public class RequestText extends Request<String> {
  @Override
  protected String method() {...}
}