如果您可以使用Class<MyEnum> c=MyEnum.class; 形式的类文字访问您的Class 对象,则意味着MyEnum 类型在编译时是已知的。在这种情况下,Class 对象是不必要的绕道。您可以使用MyEnum::methodName 形式访问MyEnum 类的所有方法,例如
Function<MyEnum,String> f=MyEnum::toString;
这就是tutorial 所描述的“对特定类型的任意对象的实例方法的引用”。它不需要实际的 MyEnum 实例。
尽管如此,当您想拥有Function<T,…> 时,处理MyEnum 毫无意义,因为该函数必须能够使用T 的任意实例,不一定是MyEnum。所以这个函数只能使用T中已有的方法,不需要在MyEnum中搜索。
由于您的目标方法不是特定于 MyEnum,这是可能的:
Function<T,String> f=T::toString;
但是as already pointed out,方法toString是在java.lang.Object中定义的,所以你也可以使用形式
Function<T,String> f=Object::toString;
作为为所有对象声明的方法也可以在T 的实例上调用。虽然这有点毫无意义,因为你也可以使用
Function<Object,String> f=Object::toString;
反映了使用Object 的任何实例的能力,而不仅仅是T。精心编写的通用代码将始终使用通配符来避免对其输入进行不必要的限制。所以它将接受一个可以使用 T 的函数(这意味着能够使用MyEnum),而不需要其类型参数与该类型完全匹配。例如:
<R> Stream<R> map(Function<? super T,? extends R> mapper)
map,应用于Stream<T> 将接受Function<Object,…>,因为Object 是T 的超类型...
因此,您可以使用T::methodName 访问该类型边界可用的所有方法,即在您的情况下,您可以使用Enum 的所有方法,当然还有Object,但没有特定于@ 的方法987654359@ 不存在于其超类型中。这与您尝试在T 的实例上应用的普通方法调用没有什么不同。此外,T 中不存在的方法无论如何都没有资格创建有效的Function<T,…>。
如果要为编译时未知的方法创建Function 实例,则必须使用反射,这是唯一需要处理Class 对象的情况(在方法的上下文中)参考)。 this answer 的第二个示例展示了如何为返回对象的实例方法创建 Function,但这实际上只适用于那些确切知道自己在做什么的人……
还要注意,这种反射式创建的 Functions 必须使用原始类型,因为它们的适当泛型类型无法声明,因为它会引用编译时不存在的类型。