74

我有以下类和接口:

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

我想创建一个方法,其中参数需要是 BasicObject 类型并实现 CodeObject。我尝试了以下代码,但不能保证 clazz 是实现 CodeObject 的类。

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

我想做这样的事情,但它不编译:

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

4 回答 4

111

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

于 2012-05-17T18:58:12.123 回答
11

这是一种有点冗长但避免泛型头痛的方法。创建另一个进行扩展/实现的类:

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

那么你的方法可以是:

public <T extends BasicCodeObject> void myMethod(Class<T> clazz) {...}
于 2012-05-17T19:28:20.650 回答
8

有两种方法可以解决您的问题,具体取决于您是要在扩展和实现的方法参数中传递类类型还是这样做的类对象。两者都有解决方案。BasicObjectCodeObject

解决方案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)

上述任一解决方案都适合您的问题,但第二个更简单。

于 2016-07-24T10:25:00.623 回答
1

如果不是所有 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)
    }
    ...
}
于 2012-05-17T18:47:26.937 回答