Java НИКОГДА НЕ передается по ссылке, верно? ... верно?[дубликат]

StackOverflow https://stackoverflow.com/questions/795160

Вопрос

Возможный Дубликат:
Является ли Java “передачей по ссылке”?

Сегодня я нашел необычный Java-метод:

private void addShortenedName(ArrayList<String> voiceSetList, String vsName)
{
     if (null == vsName)
       vsName = "";
     else
       vsName = vsName.trim();
     String shortenedVoiceSetName = vsName.substring(0, Math.min(8, vsName.length()));
     //SCR10638 - Prevent export of empty rows.
     if (shortenedVoiceSetName.length() > 0)
     {
       if (!voiceSetList.contains("#" + shortenedVoiceSetName))
         voiceSetList.add("#" + shortenedVoiceSetName);
     }
}

Согласно всему, что я читал о поведении Java при передаче переменных, сложных объектов или нет, этот код не должен делать ровно ничего.Итак um...am Я что-то здесь упускаю?Есть ли какая-то тонкость, которая была упущена мной, или этот код принадлежит thedailywtf?

Это было полезно?

Решение

Как сказал Ритмис, Java передает ссылки по значению.Это означает, что вы можете законно вызывать методы, изменяющие параметры метода, но вы не можете переназначать их и ожидать, что значение будет распространяться.

Пример:

private void goodChangeDog(Dog dog) {
    dog.setColor(Color.BLACK); // works as expected!
}
private void badChangeDog(Dog dog) {
    dog = new StBernard(); // compiles, but has no effect outside the method
}

Редактировать: В данном случае это означает , что , хотя voiceSetList мог бы изменение в результате применения этого метода (к нему может быть добавлен новый элемент), изменения в vsName не будет видно за пределами метода.Чтобы избежать путаницы, я часто отмечаю параметры своего метода final, что предотвращает их переназначение (случайно или нет) внутри метода.Это предотвратило бы компиляцию второго примера вообще.

Другие советы

Java проходит ссылки по значению, таким образом, вы получаете копию ссылки, но ссылочный объект тот же самый.Следовательно, этот метод действительно изменяет список входных данных.

Сами ссылки передаются по значению.

Из Java Как программировать, 4-е издание от Deitel & Дейтел:(стр.329)

В отличие от других языков, Java не позволяет программисту выбирать, передавать ли каждый аргумент по значению или по ссылке.Переменные примитивного типа данных всегда передаются по значению.Объекты не передаются методам;скорее, ссылки на объекты передаются в методы.Сами ссылки передаются по значению — копия ссылки передается методу.Когда метод получает ссылку на объект, метод может манипулировать объектом напрямую.

Использовал эту книгу при изучении Java в колледже.Блестящая рекомендация.

Вот хорошая статья, объясняющая это.http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

Ну, он может манипулировать ArrayList - который является объектом...если вы передаете ссылку на объект (даже передаваемую по значению), изменения в этом объекте будут отражены вызывающей стороне.В этом ли вопрос?

Я думаю, вы в замешательстве, потому что vsName изменен.Но в данном контексте это всего лишь локальная переменная, находящаяся точно на том же уровне, что и shortenedVoiceSetName.

Мне не совсем ясно, в чем именно заключается вопрос в коде.Java передается по значению, но массивы передаются по ссылке, поскольку они не передают никаких объектов, а только указатели!Массивы состоят из указателей, а не из реальных объектов.Это делает их очень быстрыми, но также делает их опасными в обращении.Чтобы решить эту проблему, вам нужно клонировать их, чтобы получить копию, и даже тогда она будет клонировать только первое измерение массива.

Для получения более подробной информации смотрите мой ответ здесь: В Java, что такое неглубокая копия? (также смотрите Другие мои ответы)

Кстати, есть некоторые преимущества, поскольку массивы - это всего лишь указатели:вы можете (ab) использовать их как синхронизированные объекты!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top