java - Java中局部变量的生命周期

标签 java class object

     public List<Map<String,class1>> methodName(String Parameter)
     {
          //create instance of List
          List<Map<Strig,class1>> list1 = new ArrayList<Map<String,class1>>();

          for(ArrayList arrayList : someGlobalList)
          {
              //create instance of class1
              //Initialize class1 with values in arrayList
              //Put this class1 as a value to tempMap which is created inside this loop
              //Put that tempMap into List
          }
       return list1;
     }  

我的疑问

我了解我们无法保证垃圾收集。但是this question表示当我们返回本地引用时不会被垃圾收集。就我而言,class1 是一个本地对象。但我正在返回list1。将调用者函数中的这些对象用作 list1.get("key") 是否安全。它将返回class1对象。我可以安全地使用类(class)成员吗?

最佳答案

只有在您的代码无法再访问对象的最后一个引用后,该对象才有资格进行垃圾回收。

让我们计算一下对新创建的对象的引用。目前,每个 class1 对象仅从列表中引用,因此让我们看看对列表本身的引用。

您有一个名为 list1 的引用。

然后你返回一个值。这将创建一个第二引用,该引用被放置在堆栈中并传递给调用者。

List<...> result = theObj.methodName("foo");

在此过程中,第一个引用 (list1) 不再可访问,但返回的引用仍然可访问 - 它将被分配给变量 result在这种情况下。因此,您仍然拥有一份有效且可访问的列表引用。因此,列表中的每个引用也是有效且可访问的。

所以是的,使用起来完全安全。

除了 Java 之外,还有其他语言可以在堆栈空间中分配对象。也就是说,对象本身是在本地分配的。返回对此类对象的引用是不安全的,因为堆栈帧会被弹出。以 C 语言为例,它返回一个指向本地数组开头的指针:

char *bad_string(void)
{
    /* BAD BAD BAD */
    char buffer[] = "local string";
    return buffer;
}

但在 Java 中,对象总是分配在堆空间中(除非内部优化对程序员不可见,并且被检查为安全,如注释中所述)。

new 运算符分配的对象永远不会“弹出”,并且始终遵守垃圾收集规则。堆栈/本地方法空间仅用于基元和引用,并且您永远不会获得对其中任何一个的引用,而只能获得对对象的引用。因此,如果您引用了某些内容,您可以相信它的内存是安全的。

关于java - Java中局部变量的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31918797/

相关文章:

c++ - 使用工厂模式按名称实例化类

c++ - 已删除的类实例上的方法仍然有效吗?

javascript - 如何将嵌套对象转换为数组的数组

java - 使用 swagger codegen 生成后端代码时添加自定义注解

java - 如何创建将添加新属性源的自定义注释

c++ - 如何使用构造函数在另一个类中创建对象?

javascript - 对象到数组返回未定义

php - 取消设置变量属性上的数组

java - 谷歌日历,如 Swing 应用程序

java - 某种 JSTL 消息标签