我有一个function
接受具有某些generic
类型的参数
公共字符串foo(T t){...}
现在... SomeA
包含可以调用的一系列方法,例如baz1()
,baz2()
,baz3()
等。
现在,这是擦
将传递给T
的变量foo(T t)
将是SomeB
或SomeC
的实例,其中SomeB extends SomeA
和SomeC extends someA
。SomeB
和SomeC
都包含返回glop(...)
的方法SomeD
,但是glop(...)
不在SomeA
中。
我希望能够传递foo(T t)
以便它接受SomeB
或SomeC
,但是,我需要调用glop(...)
(例如,如下所示)
例如。
public < T extends SomeA > String foo(T t) {
return t.glop().methodInsideOfSomeD().toString();
}
我宁愿不分别为
foo
和SomeB
(即SomeC
fooSomeB
)实现fooSomeC
。我希望能够将此方法传递给提供SomeB
或SomeC
的函数(甚至更好地包含方法glop(...)
的任何东西)。问题:我无法更改
SomeB
或SomeC
的实现或声明,因为它们驻留在我无法控制的库中。因此,我不能让它们都实现某些提供glop(...)
的接口。我只是运气不好吗?
最佳答案
请注意,使用您描述的签名定义通用方法几乎没有意义。如果类型参数T
仅用作一个或多个参数的类型,则最好通过手动擦除它来简化操作:
public String foo(SomeA t) { /* ... */ }
无论如何,您至少要有满足您要求的以下替代方案:
用两个重载的替换一个
foo()
,一个重载的类型参数以SomeB
为界,另一个重载的类型参数以SomeC
为界。假设您没有其他SomeA
子类型为此担心,考虑到SomeA
没有glop()
,这似乎是合理的。在
foo()
的实现中,使用instanceof
运算符(或Class.isInstance()
)识别SomeB
和SomeC
的实例,并对其进行适当的处理。在
foo()
中使用反射来确定参数的类是否提供具有期望签名的可访问glop()
,如果是,则以反射方式调用它。这些都不要求您以任何方式修改
SomeA
,SomeB
或SomeC
。我知道您说过您不想做(1),但这很干净而且很容易。您应该考虑一下。我希望能够将此方法传递给提供甚至更好的包含方法glop(...))的函数。
那应该是(3),也许将参数类型更改为
Object
,但是我怀疑您是否真的想要那样。反射是混乱的,通常应避免反射。