LINUX.ORG.RU

[java] вопросы


0

1

Здравствуйте! Продолжаю говнокодить на java, возникли вопросы.

Есть некий класс User. Создаем static HashMap<User>.Заполняем HashMap объектами.
Затем, где-то делаем: User user = usersMap.get(uid);
У нас в usersMap и в user будет хранится ссылка на один и тот же объект?
Если же делаем User user = usersMap.get(uid).clone();. тогда создается новый объект?
Далее, вот мы сделали User user = usersMap.get(uid);, затем с этим user провели некие манипуляции (изменили состояние объекта). Т.к. в user и в usersMap хранится ссылка на один объект, то нет смысла делать usersMap.put(user)?
И нету смысла делать user = null (потому что в HashMap все равно ссылка осталась)? Или нет?

★★★★★

> И нету смысла делать user = null (потому что в HashMap все равно ссылка осталась)? Или нет?

Чем меньше ссылок - тем лучше, хотя в случае локальной переменной это большой роли не играет.

Кстати clone не всегда делает то, что нужно, чаще всего легче сделать копию простых объектов вручную

note173 ★★★★★ ()
Ответ на: комментарий от note173

Угу, про clone() у Хорстмана читал предупреждение.

kovrik ★★★★★ ()

Если же делаем User user = usersMap.get(uid).clone();. тогда создается новый объект?

запусти код и проверь, что гадать?

Т.к. в user и в usersMap хранится ссылка на один объект, то нет смысла делать usersMap.put(user)?

нас учат делать, потому что такой скрытый линк - не сразу виден в коде.

Sonsee ()

>У нас в usersMap и в user будет хранится ссылка на один и тот же объект?
да

Если же делаем User user = usersMap.get(uid).clone();. тогда создается новый объект?

да

Далее, вот мы сделали User user = usersMap.get(uid);, затем с этим user провели некие манипуляции (изменили состояние объекта). Т.к. в user и в usersMap хранится ссылка на один объект, то нет смысла делать usersMap.put(user)?

да

И нету смысла делать user = null (потому что в HashMap все равно ссылка осталась)? Или нет?

да, осталась

JFreeM ★★★☆ ()
Ответ на: комментарий от urxvt

Еще вопрос. Поставил всякие static code analysis plugins, запустил, а они мне давай ругаться чуть ли не на каждую строчку, мол, говно у тебя, а не код.

Отсюда возникла пара дополнительных вопросов:
1.Есть такой код:

private static String getBannerKey(int projectID, String referrerID)
{
    StringBuffer key = new StringBuffer()
        .append(projectID)
        .append(DELIMETER)
        .append(referrerID);
    return key.toString();
}
Он мне ругается, мол, projectID is not assigned and could be declared final. Так же и про referrerID. И про key - Local variable key could be declared final.
Про key, как я понимаю, он ругается потому, что мы key больше не изменяем после инициализации, то можно ее сделать final? А projectID и referrerID? И вообще, он хорошие замечания мне делает или это придурь какая-то? :)

2. Так же просит делать final переменные в циклах for, например.
Т.е. типа у нас для каждой итерации создается новая переменная (пусть и одноименная), у которой область видимости - от начала цикла до его конца. Например:

for(int i = 0; i < 5; i++)
{
  final int myFinalVariable = i;
}
Так?

kovrik ★★★★★ ()
Ответ на: комментарий от kovrik

>Он мне ругается, мол, projectID is not assigned and could be declared final. Так же и про referrerID. И про key - Local variable key could be declared final.
>Про key, как я понимаю, он ругается потому, что мы key больше не изменяем после инициализации, то можно ее сделать final?
Да.

>А projectID и referrerID?
То же самое.

>И вообще, он хорошие замечания мне делает или это придурь какая-то? :)
Это сейчас мода такая - все, что можно, делать final. В принципе может улучшить производительность и предотвратить некоторые ошибки, но иногда приводит к необходимости тяжкого рефакторинга. Вон stevejobs в какой-то теме спрашивал, как ему вокруг final-поля, которое ему стало нужно менять, нагородить костылей, не убирая final.

Мода должна пройти с эволюцией компиляторов.

for(int i = 0; i < 5; i++)
{
  final int myFinalVariable = i;
}


Так?

А это я совсем не понимаю, зачм нужно.

proud_anon ★★★★★ ()
Ответ на: комментарий от proud_anon

Ага, спасибо, сделаю, как он просит :)

А это я совсем не понимаю, зачм нужно.

Это я чисто для примера привел. Что вроде как final переменные менять нельзя, а тут в цикле каждый раз новое значение присваивается - на самом деле создаются одноименные final переменные с областью видимости внутри блока for?

kovrik ★★★★★ ()
Ответ на: комментарий от proud_anon

Где-то читал, что не стоит лепить final где попало. Компилятор сам оптимизирует все как надо. final надо ставить только там, где это действительно необходимо. Например, для определения полей констант аля «private static final», для доступа к переменным метода из анонимного класса, etc.

Ian ★★ ()
Ответ на: комментарий от Ian

А как определить, где надо, а где нет? С полями-константами все понятно. А, допустим, вызываем метод, передаем ему аргументы - их можно объявить final, дабы внутри метода нельзя было по ошибке изменить переданные аргументы?

kovrik ★★★★★ ()
Ответ на: комментарий от Ian

И еще вопрос по final:
Я так понимаю, что изменяя код добавлением к переменным final, нельзя изменить код так, что RuntimeError'ы появятся? Все ошибки с final будут выявлены на этапе компиляции?


kovrik ★★★★★ ()
Ответ на: комментарий от kovrik

Я сам придерживаюсь мнения, что final нужно ставить только там, где очень надо. В частности, в аргументах метода никогда не ставлю. Однако нередко вижу код, в котором ставят.

А, допустим, вызываем метод, передаем ему аргументы - их можно объявить final, дабы внутри метода нельзя было по ошибке изменить переданные аргументы?


В этом вряд ли есть необходимость, только код лишними словами засоряется. Трудно по ошибке присвоить аргументу значение, если присваивать не собирался, и практически невозможно допустить эту ошибку так, чтобы трудно было поймать дебаггером.

proud_anon ★★★★★ ()
Ответ на: комментарий от proud_anon

Ну мне самому особо удовольствия нету везде final ставить. Но в местах, где требуется производительность, да нагрузки там большие - все-таки не будет лишним, да?

kovrik ★★★★★ ()
Ответ на: комментарий от kovrik

Что значит «изменить переданные аргументы»? Ты вполне можешь поменять ссылку у параметра метода. Параметру ты от этого плохо не сделаешь, а если он mutable, то ты его изменишь если он и final с помощью аксессоров, мутатторов(set/get) и другой дребедени, которая есть у данного класса.

В методе надо ставить final, например, если этот параметр пойдет в анонимный класс.

Ian ★★ ()
Ответ на: комментарий от kovrik

Я считаю, что будет лишним У Java компилятор умный, он сам это оптимизирует неплохо.

Но это мое сугубое IMHO. Выигрышь (а возможно даже проигрышь!) от того что что ты поставшь final не стоит того, что бы таким вот образом засорять код.

Видел код. где человек везде лепил final. Выглядит отвратно.

Ian ★★ ()
Ответ на: комментарий от kovrik

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

Имхо, final нужен только в одном случае - когда надо использовать эту переменную в анонимном вложенном классе. В остальном он смысла не имеет и только засоряет код. Если бы было как в Scala - val и var, было бы удобнее, а так куча синтаксического мусора только.

Legioner ★★★★★ ()
Ответ на: комментарий от kovrik

> на самом деле создаются одноименные final переменные с областью видимости внутри блока for?

нет, не создаются
Локальные переменные вообще не создаются - они выделяются в виде 4-байтовых ячеек перед вызовом метода, а количество ячеек считается на этапе компиляции.
final для локальных переменных - запрет модификации их в своей области видимости на этапе компиляции

note173 ★★★★★ ()
Ответ на: комментарий от note173

Да, имени у локальных переменных на самом деле тоже нет, только номер ячейки, в которой она сейчас находится

note173 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.