泛型Java 8的调用方法 [英] Calling Method on Generic Type Java 8
问题描述
我有一个函数
,该函数接受具有某些 generic
类型
I have a function
that accepts a parameter that has some generic
type
公共<T扩展SomeA>字符串foo(T t){...}
public < T extends SomeA > String foo(T t) {...}
现在... SomeA
包含一系列可以调用的方法,例如 baz1()
, baz2()
, baz3()
等...
Now... SomeA
contains a series of methods that can be called, like baz1()
, baz2()
, baz3()
, etc...
现在,这是摩擦
-
将传递给
foo(T t)
的变量T
将是SomeB
或SomeC
,其中SomeB扩展someA
和SomeC扩展someA
.
The variable
T
that will be passed intofoo(T t)
will be an instance of eitherSomeB
orSomeC
, whereSomeB extends SomeA
andSomeC extends someA
.
SomeB
和 SomeC
都包含方法 glop(...)
,该方法返回 SomeD
,但是, glop(...)
不在 SomeA
中.
Both SomeB
and SomeC
contains a method glop(...)
which returns SomeD
, however, glop(...)
is not in SomeA
.
我希望能够传递 foo(T t)
,以便它接受 SomeB
或 SomeC
,但是,我需要调用 glop(...)
(例如,如下)
I want to be able to pass foo(T t)
around so that it accepts either SomeB
or SomeC
, however, I need to call glop(...)
(e.g follows)
例如
public < T extends SomeA > String foo(T t) {
return t.glop().methodInsideOfSomeD().toString();
}
我宁愿不为 SomeB
和 SomeC
(即 fooSomeB
fooSomeC
).我希望能够将此方法传递给提供 SomeB
或 SomeC
的函数(甚至更好的是包含方法 glop(...)
).
I would rather not implement foo
separately for SomeB
and SomeC
(i.e. fooSomeB
fooSomeC
). I want to be able to pass this method around to functions providing either SomeB
or SomeC
(or even better anything that contains the method glop(...)
).
问题:我无法更改 SomeB
或 SomeC
的实现或声明,因为它们驻留在我的库中无法控制.因此,我不能让它们都实现提供 glop(...)
的接口.
The problem: I do not have the ability to change the implementation or declaration of SomeB
or SomeC
since they reside in libraries I do not control. Thus, I cannot have them both implement some interface that provides glop(...)
.
我刚好运吗?
推荐答案
请注意,使用您描述的签名定义通用方法几乎没有意义.如果类型参数 T
仅用作一个或多个参数的类型,那么您还可以通过手动擦除来简化操作:
Note that there is pretty much no point to defining a generic method with the signature you describe. If the type parameter T
is used only as the type of one or more arguments, then you might as well simplify things by manually erasing it:
public String foo(SomeA t) { /* ... */ }
在任何情况下,您至少都具有符合要求的以下替代方案:
In any case, you have at least these alternatives consistent with your requirements:
-
用两个重载替换一个
foo()
,一个重载类型参数由SomeB
限制,另一个重载类型参数由SomeB
限制> SomeC .假设您没有为此担心的SomeA
的其他子类型,考虑到SomeA
没有glop()
.
Replace the one
foo()
with two overloaded ones, one whose type parameter is bounded bySomeB
, and another whose type parameter is bounded bySomeC
. This assumes that you have no other subtypes ofSomeA
to worry about for this purpose, which seems reasonable given thatSomeA
doesn't haveglop()
.
在 foo()
的实现中,使用 instanceof
运算符(或 Class.isInstance()
)识别实例 SomeB
和 SomeC
进行处理,并对其进行适当处理.
In the implementation of foo()
, use the instanceof
operator (or Class.isInstance()
) to recognize instances of SomeB
and SomeC
, and handle them appropriately.
在 foo()
中使用反射来确定参数的类是否提供具有期望签名的可访问 glop()
,如果是,则以反射方式调用它.
Use reflection in foo()
to determine whether the argument's class provides an accessible glop()
having the expected signature, and if so, invoke it reflectively.
这些都不要求您以任何方式修改 SomeA
, SomeB
或 SomeC
.我知道您说过您不想做(1),但这很干净而且很容易.您应该考虑一下.
None of these require you to modify SomeA
, SomeB
, or SomeC
in any way. I know you said you don't want to do (1), but it's pretty clean and easy. You should consider it.
我希望能够将此方法传递给提供[...]甚至更好的任何包含方法glop(...)的函数.
I want to be able to pass this method around to functions providing [...] or even better anything that contains the method glop(...)).
那应该是(3),也许参数类型更改为 Object
,但是我怀疑您是否真的想要那个.反射很杂乱,通常应该避免.
That would be (3), maybe with the argument type changed to Object
, but I'm doubtful that you really want that. Reflection is messy, and usually it should be avoided.
这篇关于泛型Java 8的调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!