2013-12-12 4 views
1
  1. я присвоил переменную map к null:почему «нулевой» объект не может быть назначен через метод

    public static void main(String[] args){ 
        Map map = null; 
        createMap(map); 
        System.out.println("map is:" + map); 
    } 
    
  2. и я передаю переменную map к методу createMap и повторно назначен его:

    public static void createMap(Map map){ 
        if(map == null){ 
         map = new HashMap(); 
         map.put("key", "value"); 
        } 
    } 
    

и карта Variable по-прежнему «null», может кто-нибудь сказать мне, почему?

+0

Заканчивать [этот ответ] (http://stackoverflow.com/a/12429953/2024761). – SudoRahul

+1

tldr; переназначение переменной параметра * never * перепроверяет переменную, используемую в качестве аргумента в вызывающем. – user2864740

ответ

3

Для этого вам необходимо понять концепцию прохода по значению и прохода по ссылке.

Передано по значению Когда вы используете значение pass-by-value, компилятор копирует значение переданного аргумента вызывающей функции в соответствующий не указательный или не ссылочный параметр вызываемой функции. Параметр в вызываемой функции инициализируется значением переданного аргумента. Пока параметр не был объявлен как постоянный, значение параметра можно изменить, но изменения выполняются только в пределах области вызываемой функции; они не влияют на значение аргумента в вызывающей функции.
Простыми словами если есть int i = 5; и это передается функционировать void manipulate(int i) то значение 5 копируется в новое место и указатель (адрес) передается вызываемой функции, и теперь, если вы сделаете какие-либо изменения в ней они не будут быть отражены.

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

Если вы хотите, чтобы изменения будут отражаться обратно использовать проход по ссылке но Java всегда Пасс по значению для этого вы можете использовать AtomicReference

public static void createMap(AtomicReference<Map> atomicmap) 
{ 
    Map map = atomicmap.get(); 
    if(map == null) 
    { 
     map = new HashMap(); 
     map.put("key", "value"); 
    } 
    atomicmap.set(map); 
} 

public static void main(String[] args) 
{ 
     Map map = null; 
     AtomicReference<Map> atomicmap = new AtomicReference<Map>(); 
     atomicmap.set(map); 
     createMap(atomicmap); 
     map = atomicmap.get(); 
     System.out.println("map is:" + map); 
} 
+2

Не уверен, почему кто-то остановился. +1 –

0

Вы только манипулируя локальная переменная l в вашем методе createMap. Переменная map в вашем первом методе все еще указывает на null.

Чтобы понять, как это работает, рассмотрим следующее:

В вашем методе main, вы создаете varialbe map, и назначение его пустым. Теперь у вас есть эта переменная в вашем стеке, но все равно никакого соответствующего объекта в куче.

Затем вы передаете эту переменную в качестве параметра в значение createMap. Java выполняет этот вызов by value, то есть делает копию переменной и толкает ее в стек в сочетании с вызовом метода. Теперь у вас есть две переменные в стеке и все еще нет объекта в куче.

Наконец, внутри вашего метода createMap вы создаете новый объект Map и назначаете его l, вашей копии первой переменной. Теперь у вас есть две переменные в стеке, и один объект в куче, один из которых указывает на объект на карте:

карта ---> нулевой л ---> Карта

Когда createMap метод возвращает стек, и ваша переменная l освобождается. карта по-прежнему не указывает на объект карты - он никогда не делал этого, он все равно укажет на нуль. Кроме того, поскольку объект Map теперь не имеет живых ссылок, он будет замечен следующим циклом сбора мусора.

Итак, у вас в конце есть еще одна переменная в стеке, которая еще указывает на null.

0

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

public static Map createMap(Map map){ 
    if(map == null){ 
    map = new HashMap(); 
    } 
    map.put("key", "value"); // Really? 
    // More stuff. 
    return map; 
} 

А затем изменить способ вызова, как так

Map map = createMap(null); // This would then work 
0

Проходите null к createMap. Java передает все параметры по значению, а не по ссылке. Ваш метод createMap присваивает HashMapместным переменным map, а не экземпляру, который вы пробовали. Here - статья о передаче параметров.

0

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

Таким образом, вы не можете изменить ссылку, которая будет передана в. Так вы передаете

createMap(map); 

Так карта будет всегда указывать на нуль.

2
public static void createMap(Map map){ 

В коде выше, map ссылки переменная указывает на тот же объект, который проходит по методу вызывающего абонента. Но когда вы делаете это:

map = new HashMap(); 

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

Здесь:

Map map = null; // Caller reference variable 
createMap(map); 

Здесь map все еще указывает на старый объект (к сожалению, NULL в вашем случае)

Смежные вопросы