我有一个函数
,它接受一个具有某种generic
类型的参数
public < T extends SomeA > String foo(T t) {...}
现在... SomeA
包含了一系列可以调用的方法,比如baz1()
, baz2()
, baz3()
等...
现在,问题来了
将传递给
foo(T t)
的变量T
将是SomeB
或的实例>SomeC
,其中SomeB extends SomeA
和SomeC extends someA
。SomeB
和SomeC
都包含一个返回SomeD
的方法glop(...)
,但是,glop(...)
不在SomeA
中。我希望能够传递
foo(T t)
以便它接受SomeB
或SomeC
,但是,我需要调用glop(...)
(例如如下)
例如
public < T extends SomeA > String foo(T t) {
return t.glop().methodInsideOfSomeD().toString();
}
我宁愿不为 SomeB
和 SomeC
分别实现 foo
(即 fooSomeB
fooSomeC
)。我希望能够将此方法传递给提供 SomeB
或 SomeC
的函数(或者更好的任何包含方法 glop(...)
)。
问题:我无法更改 SomeB
或 SomeC
的实现或声明,因为它们驻留在我做的库中不控制。因此,我不能让它们都实现一些提供 glop(...)
的接口(interface)。
我只是运气不好吗?
最佳答案
请注意,使用您描述的签名定义泛型方法几乎没有意义。如果类型参数 T
仅用作一个或多个参数的类型,那么您不妨通过手动删除它来简化事情:
public String foo(SomeA t) { /* ... */ }
无论如何,您至少有这些符合您要求的备选方案:
将一个
foo()
替换为两个重载的,一个的类型参数由SomeB
限定,另一个的类型参数由限定>一些C
。这假设您没有为此目的担心SomeA
的其他子类型,这似乎是合理的,因为SomeA
没有glop()
.在
foo()
的实现中,使用instanceof
运算符(或Class.isInstance()
)来识别实例SomeB
和SomeC
,并适本地处理它们。在
foo()
中使用反射来确定参数的类是否提供具有预期签名的可访问的glop()
,如果是,则以反射方式调用它.
这些都不需要您以任何方式修改 SomeA
、SomeB
或 SomeC
。我知道你说过你不想做 (1),但它非常简单明了。你应该考虑一下。
I want to be able to pass this method around to functions providing [...] or even better anything that contains the method glop(...)).
那将是 (3),可能参数类型更改为 Object
,但我怀疑您是否真的想要它。反射很困惑,通常应该避免。
关于java - 泛型 Java 8 上的调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41578147/