2015-10-14 97 views
3

我想写一个使用泛型参数的Java中的方法,我想限制为三个可能的类(Field,MethodConstructor)之一。是否可以将泛型类型扩展为Java中的多个类?

我试过下面的头:

private static <T extends Field,Method,Constructor> T[] sort(T[] anArray) 

但这种方式却忽视了Method型或Constructor的泛型参数。使用下面的也产生了一个错误:

private static <T extends Field | Method | Constructor> T[] sort(T[] anArray) 

是否有可能做这样的事情在Java

+0

只是为了澄清:我们谈论的是java.reflect.Field,java.reflect.Method和java.reflect.Constructor是不是我们? – JonK

+0

是的。更具体地说,这个方法应该通过比较它们的名字来对这些类的数组进行排序(使用'java.lang.reflect'中这些类的'getName()'方法)。这就是为什么我需要限制这三个类的类型,因为并不是所有的类都有'getName'方法。显然,正如Codebender提到的那样,使用“extends Member”正是我需要的!尽管如果Java提供了一种不需要使用超类/接口的方法,这将会很酷。 – programmar

回答

5

对于你的特殊情况(如果你正在谈论Reflection的特定类),你很幸运。可以使用AccessibleObject类。

private static <T extends AccessibleObject> T[] sort(T[] anArray) 

您还可能有兴趣在根据您的要求Member接口。

3

无法使用或运算符(|)定义类型参数绑定。

这是唯一可以限制一个类型参数T扩展类和多个接口,但是,通过使用&操作:

<T extends SomeClass & FirstInterface & SecondInterface> 
2

没有,但你可以使用一个通用的接口/超类,只需使用Object并检查方法内部或提供单独的重载。

请注意,A & B将是可能的,即要求泛型类型实现这两种类型。你不能使用(即A | B),因为编译器不能/不会确定一个通用的超类型 - 如果它甚至存在于Object之外 - 因此你的实现不能在任何类型上工作,因为当怀疑你会通过错误的类型。

想一想:如果你被允许声明TT extends Field | Method,你会如何在代码中使用它?你所知道的是,这两种类型都提供了Object的方法。

泛型意味着为了访问特定类型的方法(即泛型类型的上限)而删除(可能失败)强制转换的需要。限制参数类型是因为这样做的结果,但并不是您似乎想要使用它的主要目标。这就是重载的方法。

编辑:我刚刚阅读Codebender的答案,这就是我在第一句中提到的:使用一个通用接口,或者像这里的超类一样。这可能是最好的方式。

1

Field,ConstructorMethod各自继承自Member。你可以只是做:

private static <T extends Member> T[] sort(T[] anArray) 

这是没有意义的指定类型限制可能匹配多个不相关的类型之一。泛型的全部要点是给编译器足够的信息,以确定T类型可用的方法,因为我们不确切知道T究竟是什么。如果它可以是三件事情之一,那么编译器怎么可能知道哪些方法应该被允许?