Есть ли способ в Java найти имя переменной, которая была передана функции?

У меня есть функция Java, называемая testForNull

   public static void testForNull(Object obj)
    {
     if (obj == null)
      {
        System.out.println("Object is null");
      }
    }

Я использую его для проверки нескольких объектов, чтобы убедиться, что они не равны нулю. Но я не могу назвать имя переменной таким образом.

Например, если я скажу

    testForNull(x);
    testForNull(y);
    testForNull(z);

Я не могу определить, какая из трех строк вызвала вывод "Object is null". Конечно, я могу просто добавить еще один параметр в функцию и иметь что-то вроде

    testForNull(x, "x");
    testForNull(y, "y");
    testForNull(z, "z");

Но я хочу знать, можно ли вывести имя переменной, не передавая ее явно. Благодарю.

Ответ 1

Учтите, что параметр не мог быть переменной (и поэтому не имел бы имени):

testForNull(x != y);

Ответ 2

Нет, такого пути нет. Вам нужно будет явно передать имя переменной. Однако, если ваш объект имеет поле "имя" или отображает его имя с помощью функции toString(), это может вам помочь.

Ответ 3

Для этого нужен отладчик. Невозможно сделать это программно. Что делать, если я вызываю testForNull(1 + 1). Что такое имя переменной?

Eclipse имеет графический и простой в использовании отладчик для встроенного Java. Изучение того, как использовать это, принесет дивиденды в долгосрочной перспективе, и это будет немедленное решение вашей проблемы.

Ответ 4

вы можете поместить вызов метода в foreach и установить идентификатор ссылки для каждого объекта, через который вы проходите, даже если он возвращает null или не null для этого конкретного объекта.

Ответ 5

Да, но я бы не рекомендовал его, и это было бы исключительно сложно. Вместо этого попробуйте assert:

http://docs.oracle.com/javase/1.4.2/docs/guide/lang/assert.html

Чтобы сделать то, что вы хотите, если у вас есть исходный код, получите текущий поток http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#currentThread()

Получить трассировку стека http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#getStackTrace()

Получить второй-последний элемент, имя класса, имя файла и номер строки, затем распечатать эту строку или проанализировать ее http://docs.oracle.com/javase/7/docs/api/java/lang/StackTraceElement.html#method_summary

Ответ 6

Ба, Посмотрев на исходный вопрос снова, это не стартер.

Вопрос требует, чтобы мы могли предоставить средство, с помощью которого значение, переданное в метод CheckForNull(), может получить имя значений - и здесь кикер... только тогда, когда значение равно null.

Нет абсолютно никакого способа получить что-либо от нулевого значения, отличного от String, содержащего "null" или исключение NullPointerException.

Но, как обычно, ориентация объекта на спасение. Создайте класс значений, как я упоминал выше. Теперь добавьте к нему метод isNull(). Используйте этот класс значений для любого значения, которое вы хотите сбросить отладочный текст.

Ответ 7

Java - это объектно-ориентированный язык, поэтому ответ "определенно!" вы можете указать имя переменной, переданной в качестве параметра. Для этого попробуйте это...

class Value<T> extends Object
{
    T value;
    String name;

    public Value(String name, T value)
    {
        this.name = name;
        this.value = value;
    }
}

Теперь в ваших методах вы принимаете все параметры как экземпляры Value, как в следующем методе, который принимает только значения, созданные с классами, имеющими Number в качестве базового класса (который будет Long, Float, Double и т.д.)...

public String SomeMethodWantingToKnowParameterNames(Value<? extends Number> parm1)
{
    if (parm1 != null)
    {
        // Do your work with the parameter - it name can be accessed via parm1.name
        // This is only an example
        // You would probably want to write an accessor for name
        return parm1.name;
    }

    // Return null for null
    return null;
}

И это все, что есть! Я использую общий класс, чтобы значение могло использоваться для передачи в любом виде - Floats, Longs, Double, BigInteger, String - например...

Value<Float> vFloat = new Value<Float>("MyFloat", 0.0);

Кроме того, приведенный выше метод является просто примером - на практике любой метод, принимающий значение, может получить доступ к его имени.

Удачи, и ваш код легко компилируется!

Родни