方法参数扩展类实现接口


69

我有以下类和接口:

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

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

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

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

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

这似乎是回答同一个问题:stackoverflow.com/questions/745756/...
雅尼斯

Answers:


105

您的模式类必须扩展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”又如何呢?
android开发人员

4
对我来说,仅当我仅使用T作为参数类型(无类)时,它才有效。全线:public <T extends BasicObject & CodeObject> void myMethod(T clazz)
DavidNovák2015年

然后在方法中,如何调用BasicObjectclazz对象上的getter ?
OrangePot

有没有办法在布局.xml中执行此操作? <variable name="myvar" type="T : BasicObject"/>
Cullub

哇,这甚至可以与构造函数一起使用!🎉
用户锐巴

11

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

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

然后您的方法可以是:

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

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)

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


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)
    }
    ...
}

5
是的,但我不想这样做。当然,任何方法都可以使用myMethod(Object obj)然后使用'obj.isInstance(...)',但这就是我要避免的方法。我真的希望我的方法的用户被迫传递一个好的参数。
加布2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.