我有比较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>{
}
我尝试通过instanceof
,Class<T>
和Class<Void>
,T.class
和Void.class
来比较ID。
但AndroidStudio在每个尝试过的案例中都显示错误:(
答案 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验证运行时memberOfGenericType
是Sometype
。
无论如何,作为旁注,我会说不需要泛型类型,如果你不将它用作成员,方法或方法参数的类型然后你应该重新考虑你的设计。此外,特别是类型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() {...}
}