【问题标题】:How can I delete an object passed into a Java method?如何删除传递给 Java 方法的对象?
【发布时间】:2012-09-25 21:25:31
【问题描述】:

我知道 Java 通过引用传递对象,所以当一个对象作为参数传递给一个方法时,在方法内部对参数进行的任何本地操作都会对实际对象进行。

void main(){
 String[] array1 = {"a","b","c"};
 someMethod(array1);
 print(array1.length);
}

void someMethod(String[] array){
 /..code here../
 array = null;
}

我希望在尝试打印 array1.length 时得到一个空指针异常,因为我的方法将它设置为空。然而,这并没有发生。这是有原因的吗?

【问题讨论】:

  • Java 参数总是由 value 传递。该值可能是引用变量,但它始终是按值传递的。
  • java 传递引用的值,所以这个值指向引用。一旦我们改变了对象,那个对象就会改变。但是如果我们在 mwethod 内部重新初始化它,真实的对象不会改变

标签: java pointers methods reference


【解决方案1】:

对象通过引用值(按值传递)而不仅仅是引用。

当您将null 设置为someMethod() 中的数组时,从技术上讲,它会将范围someMethod 的数组设置为null,而不是main 中的数组。

如果您还想null 外部引用,那么只需return null 而不是分配null

我建议阅读此thread 以正确理解此概念。

【讨论】:

  • 在谈论特定答案时应该使用具体的链接,而不是按位置引用它。您可以通过答案下方的“共享”链接获取永久链接。谁知道从现在起 1 年或 2 年后哪个答案的得票最多? ;) (Concrete link to referenced answer)
  • @Brian:这是正确的观点。按照您的建议更新链接。下次我会确定的。
【解决方案2】:

someMethod 中的array 只是另一个指向该对象的指针。因此,当您设置array = null; 时,您只是将指针设置为空。该对象仍然存在于堆上,并且仍然被main() 中的array1 所指向。

【讨论】:

  • 很多很棒的答案,但这是最简洁的,帮助我理解这与 c++ 有何不同。
【解决方案3】:

数组引用是按值传递的。因此,您的方法会获取对数组的引用的副本。使用此引用,您可以更改数组的内容,但如果您更改引用本身 - 即您尝试将参数设置为 null 或新数组 - 更改不会 反映在方法之外。

【讨论】:

    【解决方案4】:

    当您使用参数array1 调用someMethod 时,该方法将传递一个对array1 指向的数组的引用。本质上,现在有两个对同一个对象的引用——一个在main 范围内,一个在someMethod 范围内。如果将someMethod中的array改为指向null,这对原来的引用没有影响。

    【讨论】:

      【解决方案5】:

      你一定是来自 C++ :)

      “引用”实际上是指引用的。当一个对象被传递给一个方法时,它的引用被复制到堆栈中,所以当你设置array = null时,你实际上是在将堆栈本地array设置为null,而不是来自调用方法的实际引用.

      做你想做的事:

      void main(){
          String[] array1 = new String[] {"a","b","c"};
          array1 = someMethod(array1);
          print(array1.length); // NullPointerException thrown here
      }
      
      String[] someMethod(String[] array){
          /..code here../
          return null;
      }
      

      当你的数组开始用完空间并运行它的垃圾收集器时,Java 会自动回收你的数组使用的空间。

      将其视为类似于传递指针的副本而不是指针本身。正如您在示例中所观察到的,操作复制的指针不会更改原始指针。

      【讨论】:

        【解决方案6】:

        Java 传递引用的值,所以这个值指向引用。一旦我们改变了对象,那个对象就会改变。但是如果你在方法内部重新初始化它,那么真实的对象就不会改变; 示例如下:

        void main(){
            String[] array1 = new String[] {"a","b","c"};
            someMethod(array1);
            print(array1[0]); //you will see q
        }
        
        void someMethod(String[] array){
            array[0] = "q"; //i am NOT overriding it, I am changing the existing object
        
        }
        

        这是我将重新初始化它

        void main(){
            String[] array1 = new String[] {"a","b","c"};
            someMethod(array1);
            print(array1.length); //you will see 3
        }
        
        void someMethod(String[] array){
            array = null; //I am totally overriding the object, so it will not affect to the object inside main method.
        
        }
        

        【讨论】:

          【解决方案7】:

          您是对的 - 您在对象中更改的任何内容都会保留,但您不会更改被引用对象中的任何内容,而是引用本身就是一个值。

          【讨论】:

            【解决方案8】:

            试试:

            void main(){
             String[] array1 = {"a","b","c"};
             someMethod(array1);
             print(array1[0].length());
            }
            
            void someMethod(String[] array){
             /..code here../
             array[0] = null;
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-01-02
              • 2016-08-04
              • 2017-07-29
              • 1970-01-01
              • 2015-02-16
              • 1970-01-01
              相关资源
              最近更新 更多