Мне кажется, что спорить о «pass-by-reference vs pass-by-value» не очень полезно.
Если вы говорите: «Java - это pass-by-whatever (reference / value ) ", в любом случае вы не получите полного ответа. Вот еще одна дополнительная информация, которая, мы надеемся, поможет понять, что происходит в памяти.
Курс Crash по стеку / куче прежде, чем мы перейдем к реализации Java: значения идут и выходят из стека с хорошей упорядоченной манерой, например стопку тарелок в столовой. Память в куче (также известная как динамическая память) беспорядочна и дезорганизована. JVM просто находит пространство везде, где может, и освобождает его, поскольку переменные, которые его используют, больше не нужны.
Хорошо. Во-первых, локальные примитивы идут в стек. Таким образом, этот код:
int x = 3;
float y = 101.1f;
boolean amIAwesome = true;
приводит к этому:
[/g0]
Когда вы объявляете и создаете экземпляр объекта. Фактический объект переходит в кучу. Что происходит в стеке? Адрес объекта в куче. Программисты на С ++ назвали бы это указателем, но некоторые разработчики Java против слова «указатель». Без разницы. Просто узнайте, что адрес объекта идет в стек.
Так же:
int problems = 99;
String name = "Jay-Z";
[/g1]
Массив объект, поэтому он также попадает в кучу. А как насчет объектов в массиве? Они получают свое собственное пространство кучи, и адрес каждого объекта попадает внутрь массива.
JButton[] marxBros = new JButton[3];
marxBros[0] = new JButton("Groucho");
marxBros[1] = new JButton("Zeppo");
marxBros[2] = new JButton("Harpo");
[/g2]
Итак, что передается, когда вы вызвать метод? Если вы передаете объект, то, что вы фактически передаете, является адресом объекта. Некоторые могут сказать «значение» адреса, а некоторые говорят, что это просто ссылка на объект. Это генезис священной войны между «ссылочными» и «ценностными» сторонниками. То, что вы называете это, не так важно, как вы понимаете, что то, что передается, - это адрес объекта.
private static void shout(String name){
System.out.println("There goes " + name + "!");
}
public static void main(String[] args){
String hisName = "John J. Jingleheimerschmitz";
String myName = hisName;
shout(myName);
}
Создается одна строка, а пространство для нее выделяется в куче и адрес строки сохраняется в стеке и задается идентификатор hisName
, так как адрес второй строки такой же, как и первый, новая String не создается и не выделяется новое пространство кучи, но новый идентификатор созданный в стеке. Затем мы вызываем shout()
: создается новый стек стека и создается новый идентификатор name
и назначается адрес уже существующей строки.
[/g3]
Итак, значение, ссылка? Вы говорите «картофель».