[英]How to obtain method object for generic interface implementation in Java
In my case I want to find out if apply
method's parameter for given implementation of Guava Function
interface is annotated @Nullable
. 在我的情况下,我想确定Guava Function
接口的给定实现的apply
方法的参数是否@Nullable
注释。 Method to be implemented: 实施方法:
boolean isNullableArgument(Class<? extends Function<?,?>> function);
I don't know how to get implemented apply
method from function
class. 我不知道如何从function
类中实现apply
方法。
Eg there could be Function
implementations like this: 例如,可能有如下的Function
实现:
new Function<String,Integer>() {
public Integer apply(String input) { … }
public Integer apply(Integer input) { … }
}
Here's a quick and dirty solution. 这是一个快速而肮脏的解决方案。 Don't copy and paste it directly - it's only meant as an example to get you started. 不要直接复制和粘贴它-这只是作为入门的示例。
static boolean applyHasAnnotation(
@SuppressWarnings("rawtypes") final Class<? extends Function> functionType,
final Class<? extends Annotation> annotationType
) throws SecurityException, NoSuchMethodException {
//for each directly implemented interface,
for (final Type interfaceType : functionType.getGenericInterfaces()) {
//if the interface is parameterized,
if (interfaceType instanceof ParameterizedType) {
final ParameterizedType genericInterfaceType = (ParameterizedType)interfaceType;
//if the interface is Function
if (genericInterfaceType.getRawType() == Function.class) {
//get the type argument for T
final Type inputType = genericInterfaceType.getActualTypeArguments()[0];
//get its raw type
final Class<?> rawInputType =
(inputType instanceof ParameterizedType)
? (Class<?>)((ParameterizedType)inputType).getRawType()
: (Class<?>)inputType;
//use it to find the apply implementation
final Method applyMethod = functionType.getDeclaredMethod("apply", rawInputType);
//for each annotation on its first (and only) parameter,
for (final Annotation inputAnnotation : applyMethod.getParameterAnnotations()[0]) {
//if its type is the specified annotation type, return true
if (inputAnnotation.annotationType() == annotationType) {
return true;
}
}
return false;
}
}
}
//a more complicated inheritance hierarchy has defeated us
throw new IllegalArgumentException("Function info not found.");
}
In actuality, you'll want to code the various concerns separately: 实际上,您将需要分别编码各种问题:
F
type argument to the generic interface 在通用接口上查找F
类型参数 apply
implementation 查找apply
实施 As pointed out in the code, this solution easily breaks for more complicated type hierarchies, for example: 如代码中所指出的,此解决方案很容易打破更复杂的类型层次结构,例如:
abstract class LongFunction<T> implements Function<Long, T> { }
A new LongFunction<String> { }
would be a Function<Long, String>
but the above method would not location the generic Function
interface on its runtime type. new LongFunction<String> { }
将是Function<Long, String>
但是上述方法不会将泛型Function
接口放置在其运行时类型上。
The solution is: 解决方案是:
import com.google.common.base.Function;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Map;
import javax.annotation.Nullable;
import org.apache.commons.lang3.reflect.TypeUtils;
public class FunkUtils { private FunkUtils() {}
public static boolean isNullableArgument(Class<? extends Function> functionClass) throws Exception {
Map<TypeVariable<?>,Type> typeArgs = TypeUtils.getTypeArguments(functionClass, Function.class);
TypeVariable<?> argTypeParam = Function.class.getTypeParameters()[0];
Type argType = typeArgs.get(argTypeParam);
Class argClass = TypeUtils.getRawType(argType, null);
Method applyMethod = functionClass.getDeclaredMethod("apply", argClass);
Annotation[] argAnnos = applyMethod.getParameterAnnotations()[0];
for (int i = 0; i < argAnnos.length; i++) {
if (argAnnos[i] instanceof Nullable) return true;
}
return false;
}
}
There is a bug in TypeUtils.getTypeArguments in commons-lang3 version 3.1, but it is fixed in 3.2, that is under development now. commons-lang3版本3.1中的TypeUtils.getTypeArguments中有一个错误,但在3.2中已修复,该错误目前正在开发中。
If I got you question right, you want to do some validation of the annotation in the apply method. 如果我提出正确的问题,那么您想对apply方法中的注释进行一些验证。 You would need to use reflection this case (specially this method ). 在这种情况下,您将需要使用反射(特别是此方法 )。 It would be something like (I will just make a draft omitting the exceptions): 就像是这样(我将草拟一个省略例外的草稿):
this.getClass().getMethod("apply", parameter.getClass()).getParameterAnnotations()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.