Следите за тем, что написал Мишель. Я сам сделал другой пример, чтобы объяснить это. Я надеюсь, что это может помочь.
public static void main(String[] args){
MyParam myParam = thisIsWhy(new MyObj());
myParam.setArgNewName();
System.out.println(myParam.showObjName());
}
public static MyParam thisIsWhy(final MyObj obj){
MyParam myParam = new MyParam() {
@Override
public void setArgNewName() {
obj.name = "afterSet";
}
@Override
public String showObjName(){
return obj.name;
}
};
return myParam;
}
public static class MyObj{
String name = "beforeSet";
public MyObj() {
}
}
public abstract static class MyParam{
public abstract void setArgNewName();
public abstract String showObjName();
}
Из приведенного выше кода в методе thisIsWhy () мы фактически не присваиваем [аргумент MyObj obj] для реальная ссылка в MyParam. Вместо этого мы просто используем [аргумент MyObj obj] в методе внутри MyParam.
Но после того, как мы закончим метод thisIsWhy () , должен ли еще существовать аргумент (объект) MyObj?
Похоже, что так и должно быть, потому что мы можем видеть в основном, что мы все еще вызываем метод showObjName () , и ему нужно достичь obj . MyParam по-прежнему использует / достигает аргумента метода, даже если метод уже был возвращен!
Как на самом деле Java это делает - это создание копии также является скрытой ссылкой аргумента MyObj obj внутри объекта MyParam (но это не формальное поле в MyParam, поэтому мы не можем его увидеть )
Поскольку мы называем "showObjName", он будет использовать эту ссылку для получения соответствующего значения.
Но если мы не поставили окончательный аргумент, что приводит к ситуации, мы можем переназначить новую память (объект) на аргумент MyObj obj .
Технически нет никакого столкновения вообще! Если нам позволят это сделать, ниже будет ситуация:
- Теперь у нас есть скрытая точка [MyObj obj] для объекта [Memory A in heap], который теперь находится в объекте MyParam.
- У нас также есть еще один [MyObj obj], который является аргументом для [Памяти B в куче], теперь живущей в методе thisIsWhy.
Никаких противоречий, но "ЗАМЕДЛЕННЫЙ !!" Поскольку все они используют одно и то же "ссылочное имя", которое "obj" .
Чтобы избежать этого, установите его как «окончательный», чтобы программист не делал «подверженный ошибкам» код.