В чем преимущество назначения параметра другой переменной
Я читаю учебник с этого сайта. http://tutorials.jenkov.com/java-unit-testing/matchers.html Автор, на мой взгляд, очень опытный. Я видел код, как это. Я также видел, что кто-то еще всегда хотел присвоить параметр метода переменной, а затем использовать его внутри метода. Эта вот эта строка. protected Object theExpected = expected;
Может кто-нибудь сказать мне, в чем преимущество этого стиля кодирования? Это пытается избежать изменения статуса объекта или что-то еще?
Что делать, если параметр не является объектом, а примитивной переменной.
А что, если это неизменный объект типа String. Спасибо.
public static Matcher matches(final Object expected){
return new BaseMatcher() {
protected Object theExpected = expected;
public boolean matches(Object o) {
return theExpected.equals(o);
}
public void describeTo(Description description) {
description.appendText(theExpected.toString());
}
};
}
Вот обновление
Я просто провел еще один тест, чтобы увидеть, доступен ли этот параметр после того, как мы получили объект.
package myTest;
public class ParameterAssignTest {
public static void main(String[] args) {
MyInterface myClass = GetMyClass("Here we go");
System.out.println(myClass.getValue());
System.out.println(myClass.getParameter());
}
public static MyInterface GetMyClass(final String myString){
return new MyInterface() {
protected String stringInside = myString;
@Override
public String getValue() {
return stringInside;
}
@Override
public String getParameter() {
return myString;
}
};
}
}
Выход:
Here we go
Here we go
Значит ли это, что даже если мы присвоим этот параметр локальной переменной, он все еще работает?
3 ответа
Я не верю, присваивая theExpected
добивается всего.
Как и ожидалось, окончательный доступ к нему можно получить в анонимном классе. Если бы он был использован непосредственно в describeTo
объект не будет GC'd, и ссылка останется действительной, когда локальная область, в которой expected
был объявлен был оставлен.
Возможно, автор поста, на который вы ссылаетесь, считает, что этот явный стиль более читабелен.
Не имеет значения, если theExpected
является примитивным или Object (хотя в данном примере это Object), и является ли он изменяемым или нет.
matches
метод возвращает экземпляр анонимного класса, который расширяет BaseMatcher
(и реализует Matcher
интерфейс, при условии, что это интерфейс).
Как только он возвращает экземпляр, локальная переменная - expected
- то, что было передано ему, выходит за рамки, но theExpected
член, содержащий то же значение, что и локальная переменная, остается в экземпляре и может использоваться методами этого экземпляра.
Если вы хотите / должны использовать локальную переменную во внутреннем классе (в данном случае это анонимный локальный класс), переменная должна быть объявлена как final
независимо от того, является ли он примитивным или ссылочным типом. Это лучше объяснить здесь: почему внутренние классы Java требуют "окончательных" переменных внешнего экземпляра?, Цитирую лучшее объяснение ИМО:
Причина, по которой язык настаивает на этом, заключается в том, что он обманывает, чтобы предоставить вашим функциям внутреннего класса доступ к локальным переменным, которые они хотят. Среда выполнения создает копию локального контекста выполнения (и т. Д. В зависимости от ситуации), и поэтому настаивает на том, чтобы вы сделали все окончательно, чтобы сохранить честность.
Если этого не произошло, то код, который изменил значение локальной переменной после того, как ваш объект был сконструирован, но до запуска функции внутреннего класса, может быть странным и странным.
В этом случае создается впечатление, что автор хочет сохранить копию параметра, отправленного методу, в качестве ссылки на анонимный класс, созданный для дальнейшей оценки. Как только метод заканчивает свое выполнение, параметр Object expected
больше не доступен, поэтому, если вы хотите / должны сохранить его, вы должны назначить его в поле вашего класса.