【发布时间】:2017-12-13 10:36:26
【问题描述】:
如何从代码中代表的语言特征的特定实例中获取以下类型的对象:
- java.lang.reflect.Executable
- java.lang.reflect.Parameter
理想情况下,提供方法是获取方法的调用者或获取方法本身。
请注意,我在 SO 上找到了两种答案:
- 如何从给定的可执行对象中获取参数(很简单!)
- 如何从调用堆栈中获取方法的名称(不是签名!)
都不有助于获取名称不唯一的特定方法的参数。
特别考虑this answer 和this one 对类似问题如何掩盖对所需方法的选择。
现在,存在Class.getMethod(String, Class<?>... types),但似乎无法从现有方法定义中自动生成“类型”参数?
用例:
public class MyAssertions
{
private static final String DEFAULT_MESSAGE_NOT_NULL = "Parameter must not be null: ";
/* Ideal. */
public static void notNull(Object ref, Parameter param)
{
if(ref == null)
throw new IllegalArgumentException(DEFAULT_MESSAGE_NOT_NULL + param.getName());
}
/* Still okay. */
public static void notNull(Object ref, Executable caller, int param)
{
if(ref == null)
throw new IllegalArgumentException(DEFAULT_MESSAGE_NOT_NULL
+ caller.getParameters()[param].getName());
}
/* Hell no! */
public static void notNull(Object ref, Class<?> caller, String method, Object[] paramTypes, int param)
{
if(ref == null)
throw new IllegalArgumentException(DEFAULT_MESSAGE_NOT_NULL
+ caller.getMethod(method, paramTypes)
.getParameters()[param].getName());
}
}
【问题讨论】:
-
只是我还是您需要提供一个示例来说明您想要实现的目标?
-
恐怕,这是不可能的。另一方面,如果你在方法内部,你已经知道方法、它的签名等等。使用这些信息会直接阻碍复制和粘贴编程或重构,但无论如何这些都不应该是您的主要开发风格。 ——哦,好吧,如果你可以为调用者做这件事,也许可以开发一些简洁的工具,但是,标准 API 不支持它,甚至 Java 9 的堆栈遍历器也不支持……
-
@Eugene :给你。
-
用例不包括实际用例,即这些方法的潜在调用者。有一个技巧,如果性能无关紧要,调用者如何获得他们自己的
Method对象,但如果你想要的只是参数名称,你甚至会同时引入对参数位置的依赖关系,没有多大意义。Objects.requireNonNull(myParam, "myParam")不是比MyAssertions.notNull(myParam, 42)更简洁更简洁吗?特别是,因为后者仅在方法已使用特殊选项编译时才提供名称以保留方法参数名称?
标签: java reflection java-8