2

通常,finally无论是否在块中引发异常try或在块本身中遇到continue, breakorreturn语句,该块总是被执行。try

因此,应该更改下面给出的代码片段中方法的返回值,但它没有。

final class Product
{
    private String productName=null;

    public Product(String productName)
    {
        this.productName=productName;
    }

    public String getProductName()
    {
        try
        {
            return this.productName;
        }
        finally
        {
            this.productName="The product name has been modified in the finally block.";
            System.out.println("Product name in the finally block : "+this.productName);
        }
    }
}

public final class Test
{
    public static void main(String...args)
    {
        System.out.println(new Product("Intel core i3").getProductName());
    }
}

该方法只是在调用此方法之前getProductName()返回由构造函数分配给该字段的产品名称。productName

在此方法返回之前,在块productName中修改了的值。因此,该方法应该返回这个新的修改值,但它返回的是在构造此类的实例时finally分配给的初始值。productName


它产生以下输出:

finally 块中的产品名称:产品名称已在 finally 块中进行了修改。
英特尔酷睿 i3

为什么此方法不返回分配给块中productName字段的新值finally?它应该返回新值。不应该吗?

4

2 回答 2

5

这里的关键是您要从您的方法中返回对相应对象的引用值。而在调用方,你得到的是方法引用的副本。请记住,Java 中的所有内容都是按值传递的。甚至引用也是按值传递的。

当您使用finally块中的引用修改对象时,更改将在调用方可见。但是,如果您更改reference自身的值,那么更改当然不会反映在调用方,因为现在它们都有不同的引用。

在此方法返回之前,在 finally 块中修改了 productName 的值。

您在finally块中所做的是,您已经String为引用分配了一个新对象productName。这将改变 的参考值productName。因此,根据上述段落,更改不会反映在调用方端。他们都在处理 2 个不同的 String 对象。

因此,该方法应该返回这个新的修改值。

不,不应该。因为两个 String 对象完全不同。StringBuilder用一个对象试试这个代码:

public StringBuilder getProductName() {

    StringBuilder sb = new StringBuilder(productName);
    try {
        return sb;
    }
    finally {
        sb.append("Modified");
    }
}

现在对 的更改StringBuilder将反映在返回值中。那么这里发生了什么?

首先使用以下返回语句:

return sb;

您返回了对StringBuilder您创建的对象的引用。然后在finally块中:

sb.append("Modified");

..您已经修改了指向的对象sb。由于您没有更改其sb自身的引用值,因此对指向该对象的所有引用以及调用者端的引用都将可见对对象的更改。

现在将finally块修改为:

sb = new StringBuilder("Modified");

并查看更改是否反映。您不会看到返回值有任何变化。因为,现在你已经改变了自身的参考值sb

此外,如果您从finally块中返回修改后的引用,则原始返回值将被覆盖。尝试将您的finally块修改为:

finally {

    this.productName="The product name has been modified in the finally block.";
    System.out.println("Product name in the finally block : "+this.productName);

    return this.productName;  // Note: This is bad idea
}

现在您将看到新值。


也可以看看:

于 2013-10-14T12:54:24.857 回答
1

因为 finally 块没有做return this.productName.

try 块中的 returnthis.productName返回对象的地址。finally 块中的赋值创建了一个新对象,而返回值保持不变。

于 2013-10-14T12:55:24.893 回答