В чем смысл скопированной / дублированной ссылочной переменной?


Я только что видел следующий код:

public static void initElements(WebDriver driver, Object page) {
    final WebDriver driverRef = driver;
    initElements(new DefaultElementLocatorFactory(driverRef), page);
}

Может ли кто-нибудь сказать мне, в чем преимущество написания этого вместо:

public static void initElements(WebDriver driver, Object page) {
    initElements(new DefaultElementLocatorFactory(driver), page);
}

Я надеюсь, что мой первый вопрос здесь не слишком бессмысленный и / или глупый, и вы будете получать удовольствие, отвечая на него!

(Цитата из кода org.опенка.селен.поддержка.PageFactory ; Copyright 2007-2009 WebDriver committters; Copyright 2007-2009 Google Inc.)

4 3

4 ответа:

Нет никакой разницы в поведении приложения. Однако такой шаблон может использоваться, когда:

  • желая предоставить локальное имя значения, которое лучше подходит в этом контексте. Здесь это driverRef vs driver, что не приносит никакого значения, но в других случаях это может быть
  • хочет сделать переменную доступной в качестве локальной переменной для отладчика. Отладчики могут по-разному относиться к локальным переменным и полям классов (например, при представлении их значений), но это трудно обосновать. изменение, которое должно быть сделано постоянно
  • забота о удобочитаемости. Здесь замененное выражение просто-просто driver, но иногда у вас есть более сложное выражение, которое сделало бы строку слишком длинной, если бы она была встроена.

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

public static void initElements(final WebDriver driver, Object page) {
    initElements(new DefaultElementLocatorFactory(driver), page);
}

Я думаю, что ключевое слово "final" - это ответ на ваш вопрос.

Final означает, что ссылка не может быть переназначена.

Как уже было сказано, в коде, который вы опубликовали, нет никакого смысла.

Одна из причин создания переменной final заключается в том, что вы хотите использовать ее в анонимном внутреннем классе внутри метода. Переменная должна быть final, чтобы быть доступной внутри анонимного внутреннего класса. Несколько глупый пример, просто чтобы проиллюстрировать этот момент:

public static void initElements(final WebDriver driver, final Object page) {
    // Anonymous inner class
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            // The variables must be final, otherwise you can't access them here
            initElements(new DefaultElementLocatorFactory(driver), page);
        }
    };

    runnable.run();
}