java

时间:2015-09-11 13:54:41

标签: java pass-by-value

Java支持按值传递(总是在副本上工作)但是当你传递用户定义的对象时,它会改变实际的对象(通过引用传递但没有指针更改),我理解但为什么下面的changeObject2CLEAR方法实际上是在改变对象的价值?相反,它必须在副本上工作?

import java.util.HashMap;
import java.util.Map;

public class PassBy {

    class CustomBean {
        public CustomBean() {

        }

        private int id;
        private String name;

        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }   

        @Override
        public String toString() {
            return id + ", " + name;
        }
    }

    public Map<Integer, String> changeObject2NULL (Map<Integer, String> m) {
        m = null;
        return m;
    }

    public Map<Integer, String> changeObject2CLEAR (Map<Integer, String> m) {
        m.clear();
        return m;
    }

    public CustomBean changeCustomObject (CustomBean _e) {

        _e.setId(_e.getId() + 1);
        return _e;
    }

    public static void main(String[] args) {

    PassBy passby = new PassBy();

    Map<Integer, String> map = new HashMap<Integer, String>();
    map.put(1, "value");

    CustomBean bean = passby.new CustomBean();
    bean.setId(1);
    bean.setName("arun");

    // Initial Value
    System.out.println(map.toString());
    System.out.println(bean.toString());
    System.out.println("-------------------------");

    // Pass by value works fine
    passby.changeObject2NULL(map);
    passby.changeCustomObject(bean);

    // Custom object value changes since we pass as the object reference but Map remains with actual value
    System.out.println(map.toString());
    System.out.println(bean.toString());
    System.out.println("-------------------------");

    // Testing Pass by value - CANT UNDERSTAND why it changed the object since it has to be pass-by-value and not by ref in this case ??
    // Why setting to null not chainging the value but clear does ?
    passby.changeObject2CLEAR(map);
    System.out.println(map.toString());

    }
}

3 个答案:

答案 0 :(得分:3)

因此,让我试着帮助您理解,Java总是通过值传递,但我相信您知道所有对象实例实际上都是指向这些对象的指针。现在,当您发送一个对象时,您将传递该对象的地址值。如果对对象本身进行任何更改(如m.clear()),则转到该地址,键入转换对象并对其执行操作。但是,如果您更改指针本身,例如m = null,那么只会更改您持有的地址的副本。

答案 1 :(得分:1)

致电changeObject2CLEAR

passby.changeObject2CLEAR(map);

您正在传递实例map

方法changeObject2CLEAR

中的

public Map<Integer, String> changeObject2CLEAR (Map<Integer, String> m) {
    m.clear();
    return m;
}

您在同一个实例.clear()上执行map,即使在方法中它被称为m

作为理解练习的练习,以下方法将做同样的事情。

public void changeObject2CLEAR (Map<Integer, String> m) {
    m.clear();
}

请注意,您不必返回Map<Integer, String> m,因为您有权访问的map是在调用方法的任何地方传递的实例对象。

编辑:为什么m = null;表现为传值,m.clear()表现为传递参考?

当您将值null'分配给m时,您正在将前一个实例对象map的引用更改为null的新内存位置。< / p>

当您在实例对象.clear()上调用m方法时,您正在map引用的内存位置上的同一对象上调用该方法,因此您修改了{ {1}}对象。

答案 2 :(得分:0)

AFAIK Java仅按值传递,但值实际上是引用