本文介绍了泛型Java 8的调用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数,该函数接受具有某些 generic 类型

I have a function that accepts a parameter that has some generic type

现在... SomeA 包含一系列可以调用的方法,例如 baz1() baz2() baz3()等...

Now... SomeA contains a series of methods that can be called, like baz1(), baz2(), baz3(), etc...

现在,这是摩擦

  1. 将传递给 foo(T t)的变量 T 将是 SomeB SomeC ,其中 SomeB扩展someA SomeC扩展someA .

  1. The variable T that will be passed into foo(T t) will be an instance of either SomeB or SomeC, where SomeB extends SomeA and SomeC 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:

  1. 用两个重载替换一个 foo(),一个重载类型参数由 SomeB 限制,另一个重载类型参数由 SomeB 限制> SomeC .假设您没有为此担心的 SomeA 的其他子类型,考虑到 SomeA 没有 glop().

  1. Replace the one foo() with two overloaded ones, one whose type parameter is bounded by SomeB, and another whose type parameter is bounded by SomeC. This assumes that you have no other subtypes of SomeA to worry about for this purpose, which seems reasonable given that SomeA doesn't have glop().

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.

那应该是(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的调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-11 11:28