在方法参数上使用final关键字

经过一些自己的混淆,最终博客方法的具体含义(最终声明的方法参数)将对此博客条目进行澄清。

至少可以将方法参数上的final关键字视为Java编译器的指示符,表明该参数不能重新分配给另一个引用。 Java参数处理始终是“按值调用” (是的,即使在处理对象时也是如此),这是为什么。这是真的。当处理非原始数据类型时,Java处理对对象的引用。 对象本身不会从被调用者传递给目标函数! 而是传递一个指向所需对象的引用。 但是,此引用不等同于被调用方,因为它只是一个副本。 传递给函数的是将复制的引用作为值-好的,每个人都还在吗? :-)也许Java应该使用更匹配的解释“按复制参考调用作为值”

总结一下:

Java仅以“按值调用”样式传递所有方法参数 (原始数据类型或对对象的引用)!

为了证明这一点,让我们看一下下面的演示代码及其输出。

/**
 * Call by Value Test Application.
 *
 * @author Christopher Meyer
 * @version 0.1 
 * Apr 21, 2012
 */
public class CBVTest {

    public static void main(String[] args) {
        Integer mainInternInteger = new Integer(1);

        /*
         * Even references are copied during calls!
         *
         * Explanation Objects are never passed, only references to them, BUT
         * references are copied! So only reference COPIES reach the method.
         * Neither changes to the reference inside/outside the method will
         * influence the counterpart.
         *
         * Maybe it should be called "Call by Copied Reference as Value".
         */

        class RunMe implements Runnable {

            Integer runnerInternInteger;

            public RunMe(Integer i) {
                runnerInternInteger = i;

                /*
                 * The following operation will have no effect on the main
                 * thread, since the reference to "i" is a copied one.
                 * Interfacing the "caller" reference is prevented.
                 */
                i = new Integer(3);
            }

            @Override
            public void run() {
                while (true) {
                    System.out.println(runnerInternInteger.intValue() 
                            + "\t (runner intern value)");
                }
            }
        }

        Thread runner = new Thread(new RunMe(mainInternInteger));
        runner.start();

        // Create a new object and assign it to "mainInternInteger".
        mainInternInteger = new Integer(2);
        while (true) {
            System.out.println(
                    mainInternInteger.intValue() + "\t (main intern value)");
        }
    }
}

代码的输出如下所示:

...
2     (main intern value)
2     (main intern value)
2     (main intern value)
2     (main intern value)
1     (runner intern value)
2     (main intern value)
1     (runner intern value)
2     (main intern value)
1     (runner intern value)
2     (main intern value)
1     (runner intern value)
1     (runner intern value)
1     (runner intern value)
1     (runner intern value)
1     (runner intern value)
 ...

因此,对已处理参数的赋值(i = new Integer(3))或从调用类进行的重新赋值(mainInternInteger = new Integer(2))都不会相互影响。

那么,如果没有必要,那又有什么价值呢?

如果添加到RunMe的构造方法中(公共RunMe(final Integer i)),则重新分配i = new Integer(3)会引发异常:线程“ main”中的异常java.lang.RuntimeException:无法编译的源代码–最终参数我可能不会被分配。 它可以防止因意外重新分配而导致的故障。 意外分配给已处理的参数将始终失败! 最终迫使开发人员生成准确的代码。

final关键字不是方法签名的一部分。 因此,无论是否声明为final,编译后的代码都是相同的(每个人都可以使用diff轻松检查)。 这意味着,一旦声明了方法参数,就不会重载该方法的参数,而一旦声明则不会。 由于字节码保持相同,因此对性能也绝对没有影响。

更令人困惑的是,请记住,在可以修改变量时(例如,在处理线程的匿名内部类时,如果您不清楚在同一上下文中考虑多个变量,则内部类需要定义一个变量final)。可以更改的相同名称)。

参考:Java安全和相关主题博客 ,使用我们JCG合作伙伴 Christopher Meyer的方法参数上的final关键字


翻译自: https://www.javacodegeeks.com/2012/04/using-final-keyword-on-method.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Java中,应该只使用final关键字来声明不可变的变量,例如常量、不可变的类和不可变的方法。 这将有助于减少不必要的错误和维护程序的复杂性。 同时,建议不要使用final修饰变量,因为它们可能会降低代码的可读性和可维护性。 ### 回答2: 在Java中,final关键字用于表示不可更改的声明。使用final关键字有以下几个方面的合理用法: 1.声明final变量:当一个变量被声明为final时,它的值不能再被修改。这个特性通常用于常量的定义,可以确保常量的值在程序中不会被意外的修改。 2.声明final方法:当一个方法被声明为final时,它不能被子类重写。这样可以确保该方法能够按照开发者的意图进行执行,而不会被子类改变。 3.声明final类:当一个类被声明为final时,它不能被其他类继承。这样可以避免类的特定实现被修改或扩展,从而保护类的完整性。 4.使用final参数:当一个参数方法中被声明为final时,它的值不能在方法体中被修改。这样可以确保在方法内部不会意外地改变参数的值。 5.使用final用于同步:使用final关键字可以确保多线程环境下的安全性和可见性。当一个变量被声明为final时,在多线程中对该变量的访问将会同步进行,不会出现数据竞争的情况。 总的来说,合理使用final关键字可以提高Java程序的可读性和安全性。它可以用于定义常量、限制方法或类的修改,以及确保多线程环境的安全访问。然而,应该谨慎使用final关键字,避免过度使用,以免牺牲程序的灵活性和可维护性。 ### 回答3: 在Java中,使用final关键字可以声明不可变的常量、禁止类被继承以及锁定方法不被子类重写。 首先,可以通过final关键字定义常量。使用final关键字修饰的变量在初始化之后就不能被修改,因此它们可以被视为常量。例如,可以使用final关键字来定义一个圆周率的常量:final double PI = 3.14159; 这样,该常量的值将不能被修改。 其次,final关键字阻止类被继承。通过使用final关键字修饰一个类,可以防止其他类继承该类。这在某些情况下可能很有用,例如防止不希望被继承的类被派生出子类,从而保护类的完整性。 最后,final关键字可以锁定方法不被子类重写。通过在方法声明中使用final关键字,可以确保该方法在子类中不能被重写。这可以用来保护类中的特定实现细节,或者确保某些关键方法不被修改。 总而言之,使用final关键字可以有效地限制变量、类和方法的修改,从而增强代码的安全性和可靠性。然而,在使用final关键字时,应慎重考虑其使用场景,以免过度使用导致不必要的复杂性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值