5

为什么下面的代码可能?(只是我在处理其他代码时想出的一个例子)

public String getLogIdentifierFromFile(final File file) {
    //this.file = null; //Gives compiler error as obviously expected
    nullify(file);
    return "";
}

public void nullify(Object object) {
    object = null;
}

以及如何确保final从顶部开始的功能确实有效?这次是我制作nullify方法,但也可以是我的方法需要调用的任何人的代码。

4

6 回答 6

7

代码没有做你认为的事情。

final适用于参考。您的代码会取消原始引用的final副本。当您调用时,将获取副本finalnullify()

如果您file在调用 后检查nullify(),您会发现它保持不变。

因此,这不是final工作方式的漏洞。

于 2013-11-13T10:22:29.393 回答
2

这是因为object不在final您的第二种方法中。

所以:

public String getLogIdentifierFromFile(final File file) {
    //Have a final reference to file
    //Pass it into nullify
    nullify(file);
    //Reference to file is unchanged
    return "";
}

和:

public void nullify(Object object) {
    //get a reference to some object
    //set it to null
    object = null;
}

可以将其想象为传递一张带有togetLogIdentifierFromFile详细信息的名片,然后刮掉名片上的地址。filenullifynullify

这不影响file住在哪里,nullify只是忘记file住在哪里。

Java 在这方面有点令人困惑,因为它通过value传递对象引用。这意味着当您将引用传递给另一个方法时,它会创建引用的副本并传递该副本。

这意味着如果您对引用执行操作(例如File.setExecutable()),这些操作将在引用的对象上发生。如果您更改引用本身,即重新分配它,那么这只影响本地副本。

final仅防止重新分配引用。

于 2013-11-13T10:23:36.523 回答
2

该声明final File file仅将引用作为最终引用。这是为了确保您不会意外地将值重新分配给该变量。

在您的代码中object = null; // 'object' is not marked as a final reference. Hence it works

于 2013-11-13T10:22:09.533 回答
0

当您更改objectvar 时,您不会更改filevar - Java 通过值而不是通过引用传递参数

于 2013-11-13T10:23:03.753 回答
0

nullify函数(或与此相关的任何其他函数)接收对对象的引用,然后通过分配给它来更改引用null。它不会更改原始对象或对该对象的原始引用,因此这final是无关紧要的事实。

于 2013-11-13T10:23:45.727 回答
0
       public String getLogIdentifierFromFile(final File file) {
          //this.file = null //Gives compiler error as obviously expected
              nullify(file);
           return "";
          } 

         public void nullify(final Object object) {
          object = null; //this will produce error

          }
于 2013-11-13T10:24:00.120 回答