В Java аргументы проходят по стоимости или по ссылке?

Всегда я думал, что в Java параметры проходят по ссылке в случае объектов и по стоимости в случае примитивных типов. Но есть сайты, в которых говорится, что все параметры проходят по стоимости, например, здесь (на английском), который они показывают, что это не является верным. Я думаю, что я не понимаю различие, которое они делают. Каково объяснение?

Этот вопрос - переведенная и измененная копия оригинала Is Java “pass-by-reference” or “pass-by-value”? что является comunity wiki, оригинально написанным из-за user4315 и не обязательно представляет мнение о user4315 по этому поводу.

2
задан 23.05.2017, 15:39
1 ответ

Разъяснение с другими языками

Большая часть путаницы этой проблемы состоит в том, что используются различные определения для термина, "снабжает ссылками". Люди, которые приходят C ++, они могут понимать, что "ссылка" значит, то же самое, что и в C ++, те, что приходят C, могут думать, что он "снабжает ссылками", - то же самое, что и "указатель" в C.

Шаг ссылке (Pass by reference) в Java зависит от значения термина "снабжает ссылками".


Java прошел по стоимости (Pass by оценил)

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

Это - то, за чем оно последует:

public class Test {
    public static void main( String[] args ) {
        Perro unPerro = new Perro("Lupo");
        cambiarNombre(unPerro);
        //Print Lupo
        System.out.println( "Ahora el perro se llama : " + 
                            unPerro.obtenerNombre() );
    }

    public static void cambiarNombre(Perro p) {
        p = new Perro("Fifi");
    }
}

В этом примере, unPerro.obtenerNombre() все еще возврати "Lupo". Стоимость переменной unPerro он не sobreescrito в методе cambiarNombre с Perro названный "Fifi" ввиду того, что ссылка на объект проходит по стоимости. Это значит, чем в методе cambiarNombre проходит копия стоимости ссылки объекта Perro что находится в методе клиент (для этого случая, main). Если он проходил по ссылке, тогда unPerro.obtenerNombre() в main он возвратил бы "Fifi" позвонив в cambiarNombre так как стала отвечающей совремнным требованиям ссылка, хранившаяся в объекте Perro объявленный в методе клиент.

Для того, чтобы да менялся имя, метод cambiarNombre он был бы должен изменять состояние стоимости объекта, посланного как параметр. Этого добиваются так:

public class Test {
    public static void main( String[] args ) {
        Perro unPerro = new Perro("Lupo");
        cambiarNombre(unPerro);
        //Print Fifi
        System.out.println( "Ahora el perro se llama : " + 
                            unPerro.obtenerNombre() );
    }

    public static void cambiarNombre(Perro p) {
        p.asignaNombre("Fifi");
    }
}

А именно, с метода cambiarNombre мы можем менять контент Perro что проходит с ним, и эти изменения после окажутся отраженными в Perro снабженный ссылками из-за unPerro. Но с cambiarNombre мы не можем делать, что переменная unPerro снабдите ссылками в другой Perro.

Осуществление Perro он:

public class Perro {
    private String miNombre;
    public Perro(String nombre) {
        miNombre = nombre;
    }
    public String obtenerNombre() {
        return miNombre;
    }
    public void asignaNombre(String nombre) {
        miNombre = nombre;
    }
}

Шрифт очень обычной путаницы состоит в том, чтобы думать, что ссылки в Java и в C ++ они похожие, из-за того, что имеет то же имя. Это indiscutíblemente фальшиво. У тебя есть подробное описание этого в этом вопросе и ответе.

Этот ответ - переведенная и измененная копия первоначального ответа на английском, который является comunity wiki, оригинально написанным из-за erlando. И он не отражает обязательно мнение erlando.

15
ответ дан 01.12.2019, 08:14
  • 1
    #191; Какой-либо из тех, которые сделали-1 podr и # 237; чтобы объяснять qu и # 233; est и # 225; плохо в ответе? @JordiCastilla Относительно wiki, нет; он не имеет из-за которого быть wiki и не будет быть wiki; v и # 233; это схватывает meta.es.stackoverflow.com/a/294/301 – Jose Antonio Reinstate Monica 21.12.2015, 00:59
  • 2
    @JoseAntonioDuraOlmos Ссылки в Java не " указатели без арифметики punteros" как t и # 250; ты комментируешь. Это todav и # 237; чтобы запутывать и # 225; м и # 225; s в " novatos". Поэтому мой отрицательный обет. Если ты это исправляешь, голосовать и # 233; позитив, потому что все dem и # 225; s est и # 225; хорошо. – ArturoTena 21.12.2015, 08:33
  • 3
    Я думаю, что, если ты будешь говорить aritm и # 233; костариканская указателей тогда обязанность и # 237; схвати глубоко исследовать немного эту тему, чтобы предотвращать путаницу в лекторат, пальто в новичков. –  21.12.2015, 17:26
  • 4
    Я прекращаться и # 237; в весь параграф, который он сравнивает c ++ и java. Вопрос остается отвеченным верно с примером собаки и оставшаяся часть запутывает. Habr и # 225; люди, которые ни знали бы, или он intetese c ++. Кажись, что вопрос в ingl и # 232; s tambi и # 232; n он это оставляет ах и # 237;. – Miguel Garcia 21.12.2015, 23:22
  • 5
    @JoseAntonioDuraOlmos Хорошая идея. Услышь, уже ac и # 233; ptate твой собственный ответ aqu и # 237;. 🠘 † – ArturoTena 22.12.2015, 02:43