是否可以通过反射确定方法参数是否为最终参数?
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。
【讨论】:
以上是关于是否可以通过反射确定方法参数是否为最终参数?的主要内容,如果未能解决你的问题,请参考以下文章