在运行时,获取在Java中传递给方法的参数/参数的数量(带或不带varargs)
背景: 我正在移植另一种语言的代码。在该语言中,尾随参数始终是可选的。像:在运行时,获取在Java中传递给方法的参数/参数的数量(带或不带varargs),java,parameters,arguments,optional-parameters,optional-arguments,Java,Parameters,Arguments,Optional Parameters,Optional Arguments,背景: 我正在移植另一种语言的代码。在该语言中,尾随参数始终是可选的。像:doIt(字符串x、整数y、UUID z)这样的方法可以通过传递零、一、二或三个参数来调用 因此,该语言提供了一个countArguments函数。当将代码从该语言转换为Java时,我需要一个Java函数来替换每次出现的countArguments 对于现代Java,是否有某种方法可以获得传递给方法的参数或参数的计数 函数重载 我们有,每个人都有不同数量的论点。例如: doIt(字符串x) doIt(字符串x,整数y)
doIt(字符串x、整数y、UUID z)
这样的方法可以通过传递零、一、二或三个参数来调用
因此,该语言提供了一个countArguments
函数。当将代码从该语言转换为Java时,我需要一个Java函数来替换每次出现的countArguments
对于现代Java,是否有某种方法可以获得传递给方法的参数或参数的计数 函数重载 我们有,每个人都有不同数量的论点。例如:
doIt(字符串x)
doIt(字符串x,整数y)
doIt(字符串x,整数y,UUID z)
doIt(字符串x、整数y、UUID z、BigDecimal…)
public void doIt( String x ) {
int countArguments = … ; // Returns `1`.
}
public void doIt( String x , Integer y ) {
int countArguments = … ; // Returns `2`.
}
public void doIt( String x , Integer y , UUID z , BigDecimal... ) {
int countArguments = … ; // Returns `3`, `4`, `5`, `6`, `7`, or more.
}
如果您谈论的是从JavaScript转换,例如,函数参数未定义,并且您只有一个具有给定名称的函数,因此您必须检查实际传递的参数数量,以确定调用了函数的哪个“重载”,那么您的方法应转换为:
doIt(Object... args)
数组的长度是参数的数量
当然,在JavaScript中就是这样做的,因为参数是未定义的,并且没有重载
在Java中,您应该创建具有不同参数列表的实际重载方法,如您在问题中所示。在这些方法中,不需要检查参数的数量,因为参数列表是固定的
在方法确切知道参数的数量时(因为它们是固定的),使用代码检查参数的数量是荒谬的,因此在非varargs Java上下文中,这个问题毫无意义
最终答案:如果方法有varargs,则检查数组的长度。
如果方法没有varargs,那么检查参数计数是愚蠢的,代码不应该这样做。使用
AspectJ
,并在周围或前面添加建议。
您将得到一个JoinPoint
,只需调用JoinPoint#getArgs()代码>
瞧
旧答案。
我正在用这个特性移植另一种语言的代码。我需要一个
模拟此“计数参数”函数的方法。我需要一个函数
Java来替代对此类函数的调用
这不值得。你要做的是让它完全自动化
获取堆栈跟踪(Thread.currentThread().getStackTrace()
)
获取调用方法名称、一级和行号
使用字节码操作工具(如ByteBuddy
或ASM
)解析类,以查找实际的方法参数
当varargs存在时,将其作为输入传递给此方法(我实际上正在描述的方法)
使用varargs长度对通过解析.class找到的参数求和
没有别的办法。但这是自杀性的部分可以通过反射来实现。使用:
但请注意,由于varargs是一个数组,因此它将被视为1个参数。要获取此数组的长度,需要获取值。但使用反射无法获得任何值。在这种情况下,按照@LppEddMmmh的建议使用可能更好,我不完全确定我是否理解了这个问题。你想把这张支票放在哪里?我的意思是,它不像Javascript那样,基本上你可以输入你想要的东西。这是Java 11独有的吗?@BasilBourque每个方法都有一个定义良好的参数数量。对于varargs one,它只是一个数组,因此请查找length属性。例如,计数将为3+varargs.length如果您正在翻译代码,那么您已经解析了代码,并且知道您使用的是什么方法。如果该方法没有varargs,请用声明的参数数替换countArguments
。如果方法有一个varargs,那么用公式(N+VARARG.length)
替换countArguments
,其中N是声明参数的数量减去1,而VARARG
是varargs参数的名称。我想他想要的是完全自动化的,而不必显式传递参数
final Object[] arguments = joinPoint.getArgs();
final int count = arguments.length;
public void doIt(String x, Integer y, BigDecimal... decimals) {
int count = new Object(){}.getClass().getEnclosingMethod().getParameterCount(); // 3
}