2012-05-17 37 views
45

我有以下类和接口:方法参数延伸类实现接口

public class BasicObject{...} 
public interface CodeObject{...} 

我想创建一个方法,其中,参数需要是类型BasicObject的并实现CodeObject。我试过这段代码,但它并不保证clazz是一个实现CodeObject的类。

myMethod(Class<? extends BasicObject> clazz){...} 

我想要做somethign这样但是这个代码不编译:

myMethod(Class<? extends BasicObject implements CodeObject> clazz){...} 
+0

这似乎是回答相同的问题:http://stackoverflow.com/questions/745756/java-generics-wildcarding-with-multiple-classes – yiannis

回答

61

你的模式类必须扩展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的只是错误的语法。

+3

关于带“,” ,“CodeObject”的目的是什么?该类从“BasicObject”扩展,但“CodeObject”又如何? –

+3

对我来说,它只适用于仅使用T作为参数类型(无Class)的情况。整行: 'public void myMethod(T clazz)' –

+0

然后在该方法中,如何在clazz对象上调用属于'BasicObject'的getter? – OrangePot

0

如果不是所有BasicObjects实施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) 
    } 
    ... 
} 
+4

是的,但我不想这样做。当然,任何方法都可以使用myMethod(Object obj),然后使用'obj.isInstance(...)',但这就是我试图避免的。我真的希望我的方法的用户被迫传递一个好的参数。 – Gab

+0

那么,如果你想-force-它可以让你的程序在每次他们这样做时崩溃(或者只是抛出一个IllegalArgumentException,我相信他们会以这种方式更快地找出它) – Riking

7

这是一个有点详细的方法,但避免了泛型的麻烦。创造出不伸出/实施另一个类:

public abstract class BasicCodeObject 
    extends BasicObject 
    implements CodeObject {...} 

然后你的方法可以是:

public <T extends BasicCodeObject> void myMethod(Class<T> clazz) {...} 
4

有两种方法,这取决于您是否希望您的问题通过一项类类型在你的方法参数可以扩展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 { 

} 

,做

public void myMethod(Class<TargetClassType> clazz) 

,或者如果你想通过写对象

public void myMethod(TargetClassType clazz) 

以上两种解决方案都适合您的问题,但第二种解决方案更简单。