Reputation: 338386
Background:
I am porting code from another language. In that language, trailing arguments are always optional. A method like: doIt( String x , Integer y , UUID z )
may be called with zero, one, two, or three arguments passed.
So that language offers a countArguments
function. When translating code from that language to Java, I need a function in Java to substitute every occurrence of countArguments
.
With modern Java, is there some way to get a count of parameters or arguments passed to a method?
We have method overloading, each taking a different number of arguments. Example:
doIt( String x )
doIt( String x , Integer y )
doIt( String x , Integer y , UUID z )
And we have varargs:
doIt( String x , Integer y , UUID z , BigDecimal... )
➥ How to get the actual number of arguments passed at runtime?
Example:
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.
}
Upvotes: 1
Views: 1021
Reputation: 6290
Partly it can be done using reflection. Using getEnclosingMethod()
:
public void doIt(String x, Integer y, BigDecimal... decimals) {
int count = new Object(){}.getClass().getEnclosingMethod().getParameterCount(); // 3
}
But note, since varargs is an array it will be considered as 1 argument. To get length of this array you need to get value. But you can't get any values using reflection. In this case probably better to use AOP as suggested by @LppEdd
Upvotes: 1
Reputation: 21124
Use AspectJ
with an Around
or Before
advice.
You'll get a JoinPoint
, simply call JoinPoint#getArgs();
.
final Object[] arguments = joinPoint.getArgs();
final int count = arguments.length;
Voilà.
Old answer.
I am porting code from another language with this feature. I need a way to emulate this "count arguments" function. I need a function in Java to substitute for calls made to such a function
This is not worth it. What you'd have to do to make this totally automatic is
Thread.currentThread().getStackTrace()
)ByteBuddy
or ASM
to find the actual method arguments.No other ways. But this is suicidal
Upvotes: 0
Reputation: 159086
If you are talking about converting from e.g. JavaScript, where function arguments are undefined, and you only have 1 function with a given name, so you have to check the number of arguments actually passed to figure out which "overload" of the function is called, then your method should be translated to:
doIt(Object... args)
The length of the array is the number of arguments.
Of course, that's how you do it in JavaScript, because the arguments are undefined, and there is no overload.
In Java, you should create actually overloaded methods, with different argument lists, as you showed in the question. In those methods, there is no need to check the number of arguments, because the argument list is fixed.
Having code that checks the number of arguments when the method knows exactly how many there are (because they are fixed), is ridiculous, so the question makes no sense, in a non-varargs Java context.
Final Answer:
If method has varargs, then check the length of the array.
If method doesn't have varargs, then a check of argument count is idiotic, and the code shouldn't do it.
Upvotes: 0