我有以下类和接口:
public class BasicObject{...}
public interface CodeObject{...}
我想创建一个方法,其中参数需要是BasicObject类型并实现CodeObject。我尝试了以下代码,但它不保证clazz是一个实现CodeObject的类。
myMethod(Class<? extends BasicObject> clazz){...}
我想做这样的事情,但不能编译:
myMethod(Class<? extends BasicObject implements CodeObject> clazz){...}
答案 0 :(得分:85)
您的模式类必须扩展BasicObject
并扩展/实现CodeObject
(实际上是一个接口)。您可以使用方法签名的通配符定义中声明的多个类来执行此操作,如下所示:
public <T extends BasicObject & CodeObject> void myMethod(Class<T> clazz)
请注意,如果您通过以下任何方式执行此操作,它将无效:
public <T extends BasicObject, CodeObject> void myMethod(Class<T> clazz)
这是技术上有效的语法,但CodeObject
未使用;该方法将接受任何扩展BasicObject
的类,无论它们是否扩展/实现CodeObject
。
public void myMethod(Class<? extends BasicObject & CodeObject> clazz)
public void myMethod(Class<? extends BasicObject, CodeObject> clazz)
根据Java,这些只是错误的语法。
答案 1 :(得分:9)
这是一种有点冗长的方法,但避免了泛型问题。创建另一个执行扩展/实现的类:
public abstract class BasicCodeObject
extends BasicObject
implements CodeObject {...}
然后您的方法可以是:
public <T extends BasicCodeObject> void myMethod(Class<T> clazz) {...}
答案 2 :(得分:6)
根据您是否要在扩展BasicObject
并实现CodeObject
或的方法参数中传递类类型,有两种方法可以解决您的问题类对象这样做。两者都有解决方案。
解决方案1:
如果您想传递Class
本身,您可以执行此操作,如@bontade所述,
public <R extends BasicObject & CodeObject> void myMethod(Class<R> clazz)
如果你想传递class
个对象,你可以写
public <R extends BasicObject & CodeObject> void myMethod(R clazz)
以上是处理泛型的更复杂的方法。
解决方案2:
以下是更简单的一个。您可以定义一个抽象类,它扩展您要扩展的类并实现它:
public abstract class TargetClassType extends BasicObject implements CodeObject {
}
现在如果要传递Class本身,请执行
public void myMethod(Class<TargetClassType> clazz)
或者如果要传递类对象,请编写
public void myMethod(TargetClassType clazz)
上述任一解决方案都适合您的问题,但第二个解决方案更简单。
答案 3 :(得分:1)
如果不是所有的BasicObject都实现了CodeObject,那么你可以在方法中使用instanceof / Class.isInstance()检查(参见http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html):
myMethod(Class<? extends BasicObject> clazz)
{
if (!clazz.isInstance(CodeObject))
{
(indicate that the call was incorrect)
}
...
}