简体   繁体   中英

Get the number of variable arguments of a method in java

Beware of potentially idiotic question below:

I have a method that uses the String.format() method to format some text. Currently, it receives two parameters, so I have two "%s" parameters to create whatever text I want to.

But someone might want to use 3 parameters, or 4, or 100, with my method. How can I get the length of the passed parameters to the String.format() method as varargs, so that, in case there are 3 parameters passed to it, there will be 3 "%s" instead of the current 2 of these; or 4, or 100.

How can you obtain the number of parameters passed to the String.format() method such that the text in it automatically adds the "%s" as needed? Because the arguments are passed as just regular arguments, not as arrays or anything like that. How can you obtain the length of the argument array?

PS. This is important - I'm not talking about obtaining the (String... arguments) - there's no such thing - when someone calls your method, it uses actual parameters, the "String... arguments" is not available to grab and obtain its length.

I realize this is a badly formulated question because I don't have the code in front of me to explain further, but this has been obsessing me for quite some time - how do you obtain the number of arguments passed to a method?

For something like this:

String.format(SomeObject.SomeString, param1, param2,...,param 100)

EDIT: The SomeObject.SomeString is declared like this:

String SomeString = "Blah blah %s blah blah blah %s";

So it has two arguments that are being hardcoded in it.

When someone uses it, how do you customize SomeObject.SomeString so that it "knows" how many parameters have been passed to the String.format() method (so that SomeObject.SomeString knows how many %s to add dynamically)?

Because the arguments are passed as just regular arguments, not as arrays.

No, the values are passed as an array, therefore you could write

public String myVarags(String... args) {
    String s = "";
    for(int i = 0;i < args.length; i++)
        s += "%s ";
    return String.format(s, args);
}

It will generate a String with a %s for every argument and then format the String with the given values. It will also be a very stupid and useless method.

The varargs notation is just syntactic sugar, it's an array at runtime.

It sounds like you want to access the number of parameters that are being passed into a different method that takes a vararg as a parameter (the String.format() method).

It is not possible to know how many arguments are passed into a method if you can not change the code inside the method. And the String parameter would certainly have no idea how many parameters were passed in. It is an entirely separate object.

The only thing you can do is create a wrapper method. You can take the same varargs and then pass them along to the String.format() method making whatever changes you want to do.

Then whatever code is calling String.format() would instead need to call your wrapper method.

Example:

public String StringFormatWrapper(String...args) {
    //perform actions on the args
    if (args.length > 1) 
        args[1] = "Hello World";

    //call the String.format() method
    return String.format(args)
}

If you don't have access to what is calling String.format() then what you want to do is impossible.

I don't think what you are asking is possible because your SomeObject.SomeString is just an argument, it doesn't know anything about the other arguments. What you could do is turn your arguments into an array of varargs and create a method on SomeObject to generate the correct string:

String[] args = ...
String.format(SomeObject.createSomeString(args.length), args);

I have thought about it a bit more and I have come up with a solution for this, and the solution is a very simple one. In fact, I wrote it in 5 minutes.

Here's how it goes:

MAIN CLASS:

public class Main {

    SomeObject someObject = new SomeObject();

    public static void main(String[] args) {

        Main main = new Main();
        main.formatString("a","b","c","D","efesfs");

    }

    public void formatString(String...varargs){
        String formattedString = String.format(someObject.returnFormattedString(varargs.length), varargs);
        System.out.println(formattedString);
    }
}

SOMEOBJECT CLASS:

public class SomeObject {

    public String someString = "Blah blah blah";

    public String returnFormattedString(int numberOfArguments){
        for (int i = 0; i<numberOfArguments; i++){
            someString += "%s";
        }

        return someString;
    }
}

In other words, I'm wrapping all that stuff inside a method that will have access to how many parameters are passed as arguments, and I will pass the number of them (as varargs.length) to the method inside the SomeObject class that will take the length as an int variable and using a for loop, will add as many "%s" as needed.

It works like a charm.

I know some people criticized me that this is not "right", "it's not the right question to ask" and so on, but at least it has a simple solution, like I thought it should have, and it's not "impossible", you don't need to break down bytecode at runtime or anything crazy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM