这个问题在这里已经有答案了:

我经常遇到类似以下的方法:

public void foo(final String a, final int[] b, final Object1 c){
}

如果调用此方法而不传递最终参数,会发生什么情况。IE。稍后更改的 Object1(因此未声明为 Final)可以很好地传递给此方法

有帮助吗?

解决方案

Java 在将参数发送到方法之前总是会复制参数。这意味着最终的结果对于调用代码来说没有任何区别。这仅意味着在方法内部不能重新分配变量。(请注意,如果您有最终对象,您仍然可以更改该对象的属性)。

其他提示

有一种情况你在 必需的 将其声明为最终的(否则将导致编译错误),即将它们传递到匿名类中。基本示例:

public FileFilter createFileExtensionFilter(final String extension) {
    FileFilter fileFilter = new FileFilter() {
        public boolean accept(File pathname) {
            return pathname.getName().endsWith(extension);
        }
    };

    // What would happen when it's allowed to change extension here?
    // extension = "foo";

    return fileFilter;
}

删除 final 修饰符会导致编译错误,因为不再保证该值是运行时常量。从匿名类外部更改值将导致匿名类实例在创建后表现不同。

Java只是按值传递。(或者更好 - 按值传递引用)

所以传递的参数和方法内的参数是 两个不同的 指向同一对象(值)的处理程序。

因此如果你改变 国家 对象的属性,它会反映到引用它的每个其他变量。但是,如果您将新对象(值)重新分配给参数,则指向该对象(值)的其他变量不会被重新分配。

final 方法参数上的关键字对调用者来说绝对没有任何意义。它对于正在运行的程序也绝对没有任何意义,因为它的存在或不存在不会改变字节码。它仅确保如果在方法内重新分配参数变量,编译器会发出警告。就这样。但这就足够了。

有些程序员(比如我)认为这是一件非常好的事情并使用 final 几乎每个参数。它使理解长或复杂的方法变得更容易(尽管有人可能会认为应该重构长且复杂的方法。)它还强调了方法参数,这些参数 不是 标有 final.

考虑 foo() 的实现:

public void foo(final String a) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.print(a);
        }
    }); 
}

因为 Runnable 实例将比该方法更长寿,如果没有 final 关键词—— final 告诉编译器可以安全地获取引用的副本(以便稍后引用)。因此,它是 参考 这被认为是最终的,而不是 价值. 。换句话说:作为一个打电话的人,你不能搞砸任何事情......

最终的 意味着一旦分配该变量的值就无法更改。

同时,利用 最终的 对于这些方法中的参数意味着 它不允许程序员在方法执行期间更改它们的值。这仅意味着在方法内部 最终的 变量不能重新赋值。

如果将任何参数声明为最终参数,则无法更改它的值。

class Bike11 {  
    int cube(final int n) {  
        n=n+2;//can't be changed as n is final  
        n*n*n;  
     }  
    public static void main(String args[]) {  
        Bike11 b=new Bike11();  
        b.cube(5);  
    }  
}   

输出:编译时错误

欲了解更多详情,请访问我的博客: http://javabyroopam.blogspot.com

字符串是不可变的,因此实际上您不能在之后更改字符串(只能使保存字符串对象的变量指向不同的字符串对象)。

但是,这并不是您可以将任何变量绑定到 final 范围。所有编译器检查的是参数没有被重新分配 之内 方法。这对于文档目的很有用,可以说是良好的风格,甚至可以帮助优化字节代码以提高速度(尽管这在实践中似乎没有多大作用)。

但即使您确实在方法中重新分配了参数,调用者也不会注意到这一点,因为 java 的所有参数都是按值传递的。序列之后

  a = someObject();
  process(a);

a 的字段可能已更改,但 a 仍然是之前的对象。在引用传递语言中,这可能不是真的。

@stuXnet,我可以提出完全相反的论点。如果将对象传递给函数,并更改所传递对象的属性,则函数的调用者将在其变量中看到更改后的值。这意味着通过引用系统传递,而不是通过值传递。

令人困惑的是在系统中按值传递或按引用传递的定义,其中指针的使用对最终用户完全隐藏。

Java 绝对不是按值传递,因此,这意味着可以改变传递的对象,而原始对象不会受到影响。

请注意,您不能改变基元,只能将它们分配给变量。因此,通过参考或通过使用原语测试通过的测试不是测试。

在 Java 中不能做但在其他语言中可以做的事情就是将调用者的变量重新分配给新值,因为 Java 中没有指针,所以这会让人感到困惑。

方法输入参数中不需要final关键字。Java创建了对象引用的副本,因此将final放在上面并不会使对象成为final,而只是引用,这是没有意义的

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top