是否可以通过反射确定方法参数是否为最终参数?

Posted

技术标签:

【中文标题】是否可以通过反射确定方法参数是否为最终参数?【英文标题】:Is it possible to determine by reflection if method parameter is final? 【发布时间】:2017-12-10 10:07:40 【问题描述】:

如果方法的参数是final,是否可以查到? 我试过这个:

int modifiers = method.getParameters()[0].getModifiers() // modifiers == 0

但即使第一个参数有final 修饰符,modifiers 也会设置为零。

编辑:我真的不认为我的问题是重复的。当我使用类成员(例如字段、方法等)尝试此代码时,它可以完美运行。但是使用方法参数getModifiers 失败!

edit2:在你建议我类似的问题中,我没有找到答案......所以你能帮我,如何检查参数是否是最终的?

【问题讨论】:

只是好奇:你为什么在乎? @Ivonet 我虽然也这样,但不是。这是关于方法参数的。标题有点误导。 我认为这个answer 密切相关。当 final 应该返回 16 时,使用建议的 dupes 方法返回 0,这导致 isFinal()=false 实际上这个问题很接近这个question的副本,即使从注释的角度来看也是如此。 【参考方案1】:

简单研究一下,恐怕是不可能的。查看对此question的第一条评论

如果你查看一个反编译的类,你可以看到编译器 从所有最终参数中删除最终关键字。它是 合理,因为 final 仅在编译时才有意义。

我试图在这方面找到更多证据,但没有成功。无论如何,我根据第一个建议的配音答案做了一个小测试。

有类似的测试类

public class TestClass 
   public void testMethod(final Integer param)  // could be also int

并运行此测试/记录

@Test
public void testIsFinal() throws NoSuchMethodException, SecurityException 
   Method method = TestClass.class.getMethod("testMethod", Integer.class);
   log.info("method ", method);
   Parameter[] params = method.getParameters();
   log.info("params ", params);
   log.info("params[0] ", params[0]);
   log.info("modifiers ", params[0].getModifiers());
   log.info("final ", Modifier.isFinal( params[0].getModifiers() ));

日志

2017-12-11 13:11:24.512 INFO org.example.jpa.JUnitTest:33 - 方法 public void org.example.jpa.JUnitTest$TestClass.testMethod(java.lang.Integer) 2017-12-11 13:11:24.521 信息 org.example.jpa.JUnitTest:36 - 参数 [0] java.lang.Integer arg0 2017-12-11 13:11:24.521 信息 org.example.jpa.JUnitTest:37 - 修饰符 0 2017-12-11 13:11:24.522 信息 org.example.jpa.JUnitTest:38 - 最终错误

所以编译方法声明中似乎不存在唯一允许的方法参数修饰符final。请注意,它既不存在于记录的方法签名中

public void org.example.jpa.JUnitTest$TestClass.testMethod(java.lang.Integer)

来自source code of Modifier

public static final int FINAL            = 0x00000010;

/**
  * The Java source modifiers that can be applied to a method or constructor parameter.
  * @jls 8.4.1 Formal Parameters
  */
 private static final int PARAMETER_MODIFIERS = Modifier.FINAL;

public static boolean isFinal(int mod) 
   return (mod & FINAL) != 0;

所以告诉方法参数被声明为final第二位应该是1。

【讨论】:

以上是关于是否可以通过反射确定方法参数是否为最终参数?的主要内容,如果未能解决你的问题,请参考以下文章

通过反射获取方法的参数名称(JDK8以上支持)

Java通过反射获取带参数构造方法并使用

python 面向对象之路 方法和函数 反射

接口参数校验之@Valid与BindingResult

如何不用标定板来确定相机的外参矩阵

java中反射的三种方法是?