【问题标题】:Java Lifetime of object given reference from argument从参数给定引用的对象的 Java 生命周期
【发布时间】:2016-03-10 07:31:02
【问题描述】:

假设我有代码:

    class Foobar {
        Object item = null;
        ItemInstantiator inst = new ItemInstantiator();
        public instantiateItem() {
            inst.instantiate(item);
        }
    }

    class ItemInstantiator {
        public instantiate(Object item) {
            item = new Object();
        }
    }

由于 Foobar 类具有对在 instantiate() 中创建的新对象的实时引用,因此该新对象不应在 instantiate() 完成后被垃圾回收,对吧?

我问是因为我正在做一个项目,在这个项目中,在一个类中声明一个对象并在另一个类的方法中实例化该对象是最有意义的。问题是,一旦实例化完成,对象仍然是 null。

【问题讨论】:

  • Java 是按值传递的,因此您不能像尝试那样修改 item 参数的值。如果item 包含对某个对象的非空引用,则可以修改该对象(如果它是可变的),但不能从ItemInstantiator#instantiate() 中影响Foobaritem 的值。如果这看起来不清楚,请阅读stackoverflow.com/q/40480/18157。这与对象生命周期无关。您创建了一个新对象并立即将其丢弃。

标签: java object scope lifetime


【解决方案1】:

您在方法中实例化对象并且返回它的引用

你应该改成

class Foobar {
        Object item = null;
        ItemInstantiator inst = new ItemInstantiator();
        public instantiateItem() {
           item = inst.instantiate(item);
        }
    }

    class ItemInstantiator {
        public Object  instantiate(Object item) {
            item = new Object();
            return item;
        }
    }

清洁代码 - 敏捷软件工艺手册一书指出,一般应避免输出参数。如果你的函数必须改变某物的状态,让它改变它所属对象的状态。

请重新考虑类设计,通过传递引用实例化对象是否真的有意义。根据您的代码,这没有任何意义。您可以在不传递任何参数的情况下创建对象item

【讨论】:

  • 感谢您的精心回复。我这样做的原因是通过实例化一个列表元素递归地创建一个链表类型结构,为其分配前一个元素的指针,然后传递新元素的指针,以便可以在下一次递归时对其进行分配。我也一直在使用返回语句来获取错误代码。
  • 好的,你应该选择在一个班级里这样做。那在功能上会更具体。另外,尝试使用异常处理而不是错误代码。它会使你的代码更复杂。这只是我的看法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 2016-09-29
  • 1970-01-01
  • 1970-01-01
  • 2015-09-03
  • 1970-01-01
相关资源
最近更新 更多