方法参数extends class implements interface

Gab*_*Gab 63 java

我有以下类和接口:

public class BasicObject{...}
public interface CodeObject{...}
Run Code Online (Sandbox Code Playgroud)

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

myMethod(Class<? extends BasicObject> clazz){...}
Run Code Online (Sandbox Code Playgroud)

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

myMethod(Class<? extends BasicObject implements CodeObject> clazz){...}
Run Code Online (Sandbox Code Playgroud)

bon*_*ade 93

您的模式类必须扩展BasicObject和扩展/实现CodeObject(实际上是一个接口).您可以使用方法签名的通配符定义中声明的多个类来执行此操作,如下所示:

public <T extends BasicObject & CodeObject> void myMethod(Class<T> clazz)
Run Code Online (Sandbox Code Playgroud)

请注意,如果您通过以下任何方式执行此操作,它将无法工作:

  • 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,这些只是错误的语法.

  • 对我来说,它只有在我只使用T作为参数类型(没有Class)时才有效.全行:`public <T extends BasicObject&CodeObject> void myMethod(T clazz)` (4认同)
  • 关于","的部分,"CodeObject"的目的是什么?该类从"BasicObject"扩展,但"CodeObject"呢? (3认同)

Ste*_*eod 10

这是一种有点冗长的方法,但避免了泛型问题.创建另一个执行扩展/实现的类:

public abstract class BasicCodeObject 
    extends BasicObject 
    implements CodeObject {...}
Run Code Online (Sandbox Code Playgroud)

那你的方法可以是:

public <T extends BasicCodeObject> void myMethod(Class<T> clazz) {...}
Run Code Online (Sandbox Code Playgroud)


Ali*_*Nem 7

根据您是否要在扩展和实现的方法参数中传递类类型或者BasicObject执行此操作CodeObject类对象,有两种方法可以解决您的问题.两者都有解决方案.

解决方案1:

如果你想通过Class自己,你可以这样做,正如@bontade所解释的那样,

public <R extends BasicObject & CodeObject> void myMethod(Class<R> clazz)
Run Code Online (Sandbox Code Playgroud)

如果你想传递class对象,你可以写

public <R extends BasicObject & CodeObject> void myMethod(R clazz)
Run Code Online (Sandbox Code Playgroud)

以上是处理泛型的更复杂的方法.

解决方案2:

以下是更简单的一个.您可以定义一个抽象类,它扩展您要扩展的类并实现它:

public abstract class TargetClassType extends BasicObject implements CodeObject {

}
Run Code Online (Sandbox Code Playgroud)

现在如果你想传递Class本身,那就行了

public void myMethod(Class<TargetClassType> clazz)
Run Code Online (Sandbox Code Playgroud)

或者如果你想传递类对象,写

public void myMethod(TargetClassType clazz)
Run Code Online (Sandbox Code Playgroud)

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