Is it possible to get the name of variable passed to function in Java?

96 Views Asked by At

Sometimes I saw stack traces that said which value of which variable caused an exception to occur. So I guess it's possible to determine the name somehow. I've already searched, but haven't found anything suitable. Is this possible, and how?

What I am looking for:

public class Main {

    public static void main(String[] args) throws Exception {
        int dogs = 2;
        int cats = 3;
        printAnimals(dogs);
        printAnimals(cats);
    }

    static void printAnimals(int animal) {
        System.out.println("User has " + animal + " " + ...(animal));
    }
}

Should print:

User has 2 dogs
User has 3 cats

Edit: How can I get the parameter name in java at run time does not solve this. With

static void printAnimals(int animal) throws Exception {
    Method thisMethod = Main.class.getDeclaredMethod("printAnimals", int.class);
    String species = thisMethod.getParameters()[0].getName();
    System.out.println("User has " + animal + " " + species);
}

prints:

User has 2 animal
User has 3 animal
2

There are 2 best solutions below

1
Thomas Kläger On BEST ANSWER

Sometimes I saw stack traces that said which value of which variable caused an exception to occur.

If by that you mean a message like

java.lang.NullPointerException: Cannot load from object array because "a[2]" is null

This was added to the JVM due to JEP 358: Helpful NullPointerExceptions. It is only applicable to NullPointerExceptions and it only resolves field names and possibly local variable names / parameter names (local names if the code is compiled with debug information, parameter names if it is compiled with debug information or parameter name information).

Even this code cannot resolve the names of variables in the calling method.

One problem with such a hypothetical feature that could resolve variable names in the calling method: what should it return as variable name if you call your method as

printAnimals(42);
2
k314159 On

What you're doing is usually done using a Map rather than individual variables. So instead of

    int dogs = 2;
    int cats = 3;

you would have:

    Map<String, Integer> animalNumbers = Map.of(
        "dogs", 2,
        "cats", 3
    );

    for (var entry : animalNumbers)
        printAnimals(entry);

...

static void printAnimals(Map.Entry<String, Integer> animal) {
    System.out.println("User has " + animal.getValue() + " " + animal.getKey());
}

You might also want something like:

Map<String, String> plurals = Map.of(
    "dog", "dogs",
    "cat", "cat",
    "mouse", "mice",
    "ox", "oxen"
);

and use it to select singular or plural according to the number of animals (this generally works in English but it's more complicated in other languages).