Ros*_*han 2 java final inner-classes
在java Program中,参数String在方法声明中定义.但是在方法定义中,它作为final String变量被访问.是否会导致一些问题(如安全性,内存问题)?
例如:
方法声明
join(String a,String b);
Run Code Online (Sandbox Code Playgroud)
方法定义
public void join(final String a,final String b)
{
Authenticator au = new Authenticator(){
public PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(a,b)}
};
}
Run Code Online (Sandbox Code Playgroud)
请帮助我,澄清我的疑虑.提前致谢
PS我正在访问a和b作为最终变量,因为我必须在内部类中使用它.
pol*_*nts 18
final只是意味着不能为引用/原始变量分配新值.它与const概念不同(Java没有); 它不保证不变性.String当然,在Java中已经足够不可变(除非讨厌的反射攻击).
final对参数参数使用修饰符对安全性或垃圾回收没有影响.这样做是为了提高可读性并强制执行编码约定,即参数变量不会在方法中重用以存储其他值.
在遇到final修饰符时,可以确保人类读者在分配后,该变量的值不会在其范围内发生变化.编译器会强制执行此行为,并且不会编译非法尝试为声明的变量赋值的程序final.
JLS 14.2.4
final变量可以声明变量
final.甲final变量可以仅被分配给一次.如果final赋值变量,则为编译时错误,除非在赋值之前明确未分配.
然而,如上所述,final本身并不保证所涉及的对象的不变性.一个final StringBuilder sb声明保证sb,一旦分配,并在其范围内,将不参考另一个StringBuilder实例.StringBuilder当然,它本身就是一个可变对象.
final 和内部阶级final修饰符的另一个用途是允许内部类使用局部变量等:
JLS 8.1.3内部类和封闭实例
必须声明使用但未在内部类中声明的任何局部变量,形式方法参数或异常处理程序参数
final.
这与使用这些变量的内部类如何用Java编译有关,这个实现细节可能与讨论不太相关.本质上,这些final变量的值在构造时被赋予内部类.内部类实例不会看到对局部变量的后续更改(如果允许).为了确保正确的语义,必须声明这些局部变量final.
final修饰符对局部变量的影响final局部变量/形式方法参数的修饰符是编译时概念,并且不存在于字节码级别(即,它final与字段,类和方法的修饰符起着非常不同的作用).因此,这个概念在运行时根本就不存在,其中final非final局部变量是无法区分的; 关键字本身的使用不会对垃圾收集和/或性能产生任何影响.
垃圾收集性是根据是否存在对象的实时引用来定义的.无论是否声明它们,局部变量和方法参数都超出了方法末尾的范围(或它们声明的块)final.超出范围意味着参考"死".对象本身可能仍然有来自其他地方的实时引用.
在这种特殊情况下,声明形式方法参数,final以便它们可以在内部类中使用.如上所述,内部类将复制这些引用以供自己使用.因此,在这种特定情况下,Authenticator对象将引用String由a和引用的对象b.
简单地说,对一个对象的引用越多,就越难以成为垃圾难以收集的垃圾.然而,潜在因素是这些参考文献的活跃性,而不是它们是否存在final.
理解这些概念以清除对内存使用/性能问题的任何疑问是很好的.最好只是分析并查看问题是否真实,并根据需要进行修复.精心设计的系统应该能够高度适应这些变化.