Java 将泛型类型与 Void 进行比较
Posted
技术标签:
【中文标题】Java 将泛型类型与 Void 进行比较【英文标题】:Java compare generic type with Void 【发布时间】:2015-01-31 20:20:30 【问题描述】:我在比较 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 在每个尝试过的情况下都会向我显示错误:(
你能帮我比较一下吗? 谢谢。
【问题讨论】:
您遇到了什么错误?他们可能会解释为什么每种方法都不起作用...... 我不确定该代码的用途是什么,但 Void 是一个不可实例化的类,因此 intanceof 将始终返回 false 我想使用它来确保 Request 的子类中更详细的泛型类型。我在父子类的其他方法中使用它 【参考方案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
语句无用。
【讨论】:
如果我像你的例子那样做,那么它就会让我出错: if(member instanceof Void) //Incovertible types;无法将 T 转换为 java.lang.Void 我没有收到任何编译错误。你确定你没有搞混什么吗? "if" 将始终返回 false,因为 (null instanceof Anything) 为 false,根据 instanceof 的定义:***.com/questions/2950319/… @kocko -- 但这会让你的答案成为非答案:“你可以这样做”+“这样做总是错误的”==“不要这样做” 【参考方案2】:你不能那样使用 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】:Guice 使用的访问参数类的更好方法是使用这样一个事实:虽然泛型类无法访问其自己的“类”参数,但其子类确实可以访问对于这些论点:见https://***.com/a/18610693/15472
如果你需要这个,要么使用 Guice'TypeLiterals
,要么重新实现他们的逻辑。
【讨论】:
【参考方案4】:由于在 Java 中没有对象是 Void
类型的实例,因此您不能在此处使用 instanceof
。
null
是唯一属于Void
类型成员的值。所以也许你想做的是这个?:
if (memberOfGenericType == null)
runAnotherMethod();
关于类型Void
不能创建Void
类型的对象,因为该类只有一个私有构造函数,并且从不从类中调用它。 Void
通常用于这些情况:
Class
对象,该对象表示声明为返回void
的方法的返回类型。
作为占位符类型参数,当该类型的字段和变量不打算使用时。
【讨论】:
【参考方案5】:使用 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);
【讨论】:
【参考方案6】:在运行时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() ...
【讨论】:
以上是关于Java 将泛型类型与 Void 进行比较的主要内容,如果未能解决你的问题,请参考以下文章