在Java中,如何返回对对象的引用,以便可以使用赋值运算符修改对象

Posted

技术标签:

【中文标题】在Java中,如何返回对对象的引用,以便可以使用赋值运算符修改对象【英文标题】:In Java, how do you return reference to an object, so the object can be modified using assignment operator 【发布时间】:2017-05-03 04:56:21 【问题描述】:

我了解 Java 按值传递所有内容,包括引用。由于被调用函数具有形式参数对象的副本——引用的副本——它不能使用默认赋值运算符 (=) 修改原始对象。我假设引用等同于 C 中的指针——它保存实际对象变量的地址。

编辑:尽管其他问题也提出了类似的问题,但我试图查看是否可以使用赋值运算符重载赋值运算符以使交换工作 - 了解到 Java 不支持用户定义的运算符重载。另外,我希望有人可以提供一种使其工作的新方法。

这是我创建的一个类来测试这个概念,看看我是否可以在对象声明的范围之外获取实际对象。

public class Time 
    public int currentTime = 0;
    public static int iD =0 ;
    public final int uniqueObjId = iD;
    public Time(int settingTime) 
        currentTime = settingTime;
        iD++;
    

    public int getTime() 
        return currentTime;
    

    public static long getCurrTime() 
        return System.currentTimeMillis();
    

    public void setTime(int currentTime) 
        this.currentTime = currentTime;
    

    public static void main(String[] args) 
        Time t1 = new Time(100);
        Time t2 = new Time(200);

        System.out.println("Before testInt is " + t1.getTime());
        System.out.println("Before testInt2 is " + t2.getTime());
        System.out.println("testInt Objectid is " + t1.uniqueObjId);
        System.out.println("testInt2 Objectid is " + t2.uniqueObjId);

        swap(t1, t2);

        System.out.println("testInt is " + t1.getTime());
        System.out.println("testInt2 is " + t2.getTime());


    
    public static void swap(Time x, Time y)

        Time temp = new Time(300);
        System.out.println("Before x is " + x.uniqueObjId);
        System.out.println("Before y is " + y.uniqueObjId);
        System.out.println("Before temp is " + temp.uniqueObjId);

        x = x.getObj();
        y = y.getObj();
        temp = x;
        x = y;
        y = temp;
        System.out.println("After x objectId is " + x.uniqueObjId);
        System.out.println("After y objectId is " + y.uniqueObjId);
        System.out.println("After temp objectId is " + temp.uniqueObjId);
    
    public Time getObj()
    return this;
    

结果如下:

Before testInt is 100
Before testInt2 is 200
testInt Objectid is 0
testInt2 Objectid is 1
Before x is 0
Before y is 1
Before temp is 2
After x objectId is 1
After y objectId is 0
After temp objectId is 0
testInt is 100
testInt2 is 200

根据结果,x 和 y 指向 main() 中声明的实际对象 t1 和 t2,但是,将 t1 分配给 temp,将 t2 分配给 t1,最后将 temp 分配给 t2 并不会复制它们的成员,主要是当前时间变量。所以我假设一种方法来获得实际赋值,其中对象的所有成员都被复制到对象范围之外是重载默认赋值运算符?请让我知道重载赋值运算符是否会执行实际赋值,而不仅仅是将当前变量指向另一个变量的引用对象。

【问题讨论】:

旁注:java 引用不等同于 C 指针。它们不必通过直接存储对象的地址来实现。 (还有其他区别) 你不能交换,就像在 c 中一样。你可以这样做y = swap(x, x=y) 和交换函数返回 x。 重载赋值运算符也不行? Java 没有运算符重载。 Java: Why does this swap method not work?的可能重复 【参考方案1】:

您需要返回 x 和 y 的值并分配给 t1 和 t2。 在 main() 中:-

List<Time> list = swap(t1,t2);
t1 = list.get(0); t2 = list.get(1);

并改变swap()如下:

public static List<Time> swap(Time x, Time y)

    Time temp = new Time(300);
    System.out.println("Before x is " + x.uniqueObjId);
    System.out.println("Before y is " + y.uniqueObjId);
    System.out.println("Before temp is " + temp.uniqueObjId);

    x = x.getObj();
    y = y.getObj();
    temp = x;
    x = y;
    y = temp;
    List<Time> list = new ArrayList<Time>();
    list.add(x);
    list.add(y);
    System.out.println("After x objectId is " + x.uniqueObjId);
    System.out.println("After y objectId is " + y.uniqueObjId);
    System.out.println("After temp objectId is " + temp.uniqueObjId);
    return(list);

【讨论】:

以上是关于在Java中,如何返回对对象的引用,以便可以使用赋值运算符修改对象的主要内容,如果未能解决你的问题,请参考以下文章

1如何声明一个类?如何创建类的对象?

java数组作为参数传入函数怎么让他不变化

java RMI 如何返回远程对象的引用

Java 的垃圾回收如何判断哪个对象可以被回收

无法用无名对象对引用赋初值

详解Java中对象的软弱和虚引用的区别