java - 关于Java中的局部final变量

标签 java final inner-classes

在java程序中,参数在方法声明中定义为String。但在方法定义中,它作为 final String 变量进行访问。是否会导致一些问题(如安全、内存问题)?

例如:

方法声明

join(String a,String b);

方法定义

public void join(final String a,final String b)
{
    Authenticator au = new Authenticator(){
        public PasswordAuthentication getPasswordAuthentication(){
        return new PasswordAuthentication(a,b)}
    };
}

请帮我解答一下我的疑惑。提前致谢

附注我将 a 和 b 作为最终变量访问,因为我必须在内部类中使用它。

最佳答案

final 只是意味着不能为引用/原始变量分配新值。它与const概念不同(Java没有);它保证不变性。当然,Java 中的 String 已经足够不可变了(除非出现讨厌的反射攻击)。

对参数参数使用final修饰符不会对安全性或垃圾回收产生影响。这样做是为了提高可读性并强制执行编码约定,即参数变量不会在方法中重用来存储其他值。

在遇到final修饰符时,人类读者可以放心,该变量的值一旦分配,就不会在其范围内改变。编译器将强制执行此行为,并且不会编译非法尝试为声明为 final 的变量分配新值的程序。

JLS 14.2.4 final Variables

A variable can be declared final. A final variable may only be assigned to once. It is a compile time error if a final variable is assigned to unless it is definitely unassigned immediately prior to the assignment.

但是,正如前面提到的,final 本身并不保证所引用的对象的不变性。 final StringBuilder sb 声明保证 sb 一旦被分配并在其范围内,就不会引用另一个 StringBuilder 实例。 StringBuilder 本身当然是一个可变对象。

<小时/>

final 和内部类

final 修饰符的另一个用途是允许内部类使用局部变量等:

JLS 8.1.3 Inner Classes and Enclosing Instances

Any local variable, formal method parameter or exception handler parameter used but not declared in an inner class must be declared final.

这与使用这些变量的内部类在 Java 中的编译方式有关,这个实现细节可能与讨论不太相关。本质上,这些final变量的值在构造时被赋予内部类。内部类实例将看不到对局部变量的后续更改(如果允许)。为了确保正确的语义,这些局部变量必须声明为 final

<小时/>

final 修饰符对运行时局部变量的影响

用于局部变量/形式方法参数的

final 修饰符是一个编译时概念,并且不存在于字节码级别(即,它与 final 起着非常不同的作用)字段、类和方法的 修饰符)。因此,这个概念在运行时根本不存在,其中 final 和非 final 局部变量是无法区分的;关键字本身的使用不会对垃圾回收性和/或性能产生任何影响。

垃圾可收集性是根据是否存在对对象的实时引用来定义的。局部变量和方法参数在方法末尾(或声明它们的 block )超出范围,无论它们是否声明为 final。超出范围意味着引用“已死”。对象本身可能仍然有来自其他地方的实时引用。

在这种特殊情况下,形式方法参数被声明为final,以便它们可以在内部类中使用。如上所述,内部类将复制这些引用以供自己使用。因此,在这种特殊情况下,Authenticator 对象将引用 ab 引用的 String 对象>.

简单地说,对对象的引用越多,就越难将其认定为难以收集的垃圾。然而,根本因素是这些引用的活跃度,而不是它们是否最终

<小时/>

关于分析

理解这些概念有助于消除对内存使用/性能问题的任何疑问;最好只进行分析并查看问题是否真实,并根据需要进行修复。一个设计良好的系统应该能够高度适应这些变化。

关于java - 关于Java中的局部final变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3013547/

相关文章:

java - 从 Eclipse 将带有库的项目导出到可运行的 jar

java - 在 android 中通过 httpconnection 查询时,位置自动完成 url 不返回任何内容

java - java方法参数中的final

c++ - 编译器如何从 C++ 的新 final 关键字中受益?

java - 如何在匿名类中引用更高的类

java - 将多个 android 设备连接到 "main"pc 应用程序

java - Spring @Qualifier 在继承接口(interface)时不起作用

java - `final` 关键字等效于 Python 中的变量?

java - 为什么javac要创建一个额外的类?

java - 在java单例中获取内部类的实例