Переменные экземпляра передаются по ссылке в Java? - PullRequest
0 голосов
/ 11 марта 2011

Теперь я знаю, что Java является чисто передаваемой по значению, но переменные экземпляра передаются по ссылке?

Вот что я имею в виду (и я знаю, что этот код ужасен, но это псевдокод:

//Instance variables
private Object[] array = new Object[10];
array[4] = new Object[5];

//Private method
private Object ar(int x)
{
     return array[x];
}

//Inside Main or some other method
ar(4)[0] = "Foo";

Теперь, будет ли первый слот в массиве в array[4] изменен на "Foo", потому что array является переменной экземпляра?

Для уточнения:

Я знаю, что ВСЕ передается по значению. Но мы говорим о вызове вещей, содержащихся в переменных экземпляра, пожалуйста, обратите внимание на это. Спасибо.

Ответы [ 8 ]

5 голосов
/ 11 марта 2011

Да, первый слот в array[4] будет изменен на "Foo"

В Java все передается по значению. При передаче объектов ссылка на объект передается по значению. Например, объект, содержащийся в array[4], возвращается из метода ar.

4 голосов
/ 11 марта 2011

Переменные никогда не передаются. Только те значения, которые они содержат. То есть: не имеет значения, является ли она переменной экземпляра или иным образом (по крайней мере, ради аргумента "что пропущено").

Помните, что объект является тем, чем он является, и нет неявного копирования / клонирования / дублирования объектов - это включает в себя объекты массива - самих себя (примитивы считают самоизображаемыми неизменяемыми лица).

Удачного кодирования.


Обновление: Я нашел эту ссылку, и она мне нравится. Вызов по объекту . Этот термин приписывается Лискову.

Но не берите в голову, единственное, что вам нужно знать, это то, что модель Python Java не является ни «вызовом по значению», ни «вызовом по ссылке» (потому что любая попытка использует [ думать в] этих терминах [думает в этих терминах] ...) Наиболее точное описание - CLU «вызов по объекту» или «вызов путем совместного использования» . Или, если хотите, «вызов по ссылке на объект».

Это сумма разниц:

"В частности, он не называется по значению, потому что мутации аргументы, выполняемые вызываемой подпрограммой, будут видны звонящий. И ЭТО НЕ ВЫЗЫВАЕТ ПО ССЫЛКЕ, потому что не передается переменным вызывающего, а только определенному объекты ".

Только в Java «вызов по совместному использованию» реализован с «передачей значения ссылки» - деталь реализации, которую не нужно рассматривать для описания вызывающей семантики, объектов или объекта -identity .

1 голос
/ 11 марта 2011

Java Lang Spec: http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.1

§4.1 Существует ... два вида данных значения , которые можно ... передавать в качестве аргументов ...: примитивные значения (§4.2) и ссылочные значения

§4.3. Эталонные значения (часто просто ссылки ) являются указателями на эти объекты

Таким образом, Java передается по «значению», или «справочному значению», или «справочнику», или «указателю». (игнорируя примитивы)

Все 4 версии утверждены языковой спецификацией.

Теперь мы можем остановить эту игру в слова. Мы все знаем, что прошло, разве этого недостаточно? Как насчет того, чтобы мы назвали это «мимо мимо»?

1 голос
/ 11 марта 2011

От авторов Java: «В Java существует ровно один режим передачи параметров - передача по значению - и это помогает упростить процесс».Язык программирования Java, 2-е изд.Кен Арнольд и Джеймс Гослинг, раздел 2.6.1, стр. 40, третий абзац.

0 голосов
/ 11 марта 2011

Я знаю, что ВСЕ передается по значению.Но мы говорим о вызове вещей, содержащихся в переменных экземпляра, пожалуйста, сфокусируйтесь на этом.Спасибо.

ВСЕ включает «вещи, содержащиеся в переменных экземпляра».

Конечно, это очевидно?

0 голосов
/ 11 марта 2011

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

(термины «по ссылке», «по стоимости», «экземпляр» в этом контексте неоднозначны и сбивают с толку.)

0 голосов
/ 11 марта 2011

Ну, я вроде как ответил на свой вопрос, выполнив довольно простой тест, но некоторые из ответов, которые уже были оставлены, помогли многое прояснить. Я знаю что-то вроде 14 языков программирования, поэтому какой язык делает то, что иногда становится немного размытым.

public class ArrayPassTest {

    private Object[] array;

    public ArrayPassTest()
    {
        array = new Object[10];
        array[4] = new Object[10];
    }

    public Object[] ar(int x)
    {
        return (Object[])array[x];
    }

    public static void main(String[] args) {
        ArrayPassTest apt = new ArrayPassTest();

        apt.ar(4)[0] = "Foo";

        System.out.println(apt.ar(4)[0]);
        System.out.println(apt.ar(4)[5]);

    }

}

выходы:

Foo
null

Спасибо за помощь!

0 голосов
/ 11 марта 2011

Да, этот код установит array[4][0] в "Foo".Тот факт, что array является переменной экземпляра, не имеет значения.

...