最近项目刚上完线,我又清闲了于是深入学习下final,有很多细节以前真没注意。
1.final修饰类
- 表示这个类不能被继承,如String
- final类中的所有成员方法都会被 隐式地指定为final方法
2.修饰方法
《 Java 编程思想》:
注:类的 private 方法会隐式地被指定为final方法。
3.修饰变量
对于一个final变量,如果是基本数据类型的变量,则其 数值一旦在初始化之后便不能更改 ;如果是引用类型的变量,则在对其初始化之后便 不能再让其指向另一个对象 。
重新赋值会编译报错,如上。
1.类的final变量和普通变量有什么区别?【重点】
java是这样设计的:final一生只认一个值,你初始化好了,他就不能在重新赋值。
当用final作用于类的成员变量时, 成员变量 (注意是类的成员变量, 局部变量 只需要保证在使用之前被初始化赋值即可)必须在定义时或者 构造器 中进行初始化赋值
运行结果: true false
final在编译器就确认了值
这段代码的输出结果为false,方法getHello编译器不能确定。
2.被final修饰的引用变量指向的对象内容可变吗?
内容可变,不变的是 地址 ,记住是地址,这个面试经常考。
3.final和static
- static保证只有独一份
- final保证值不变,记住引用变量 内容是可以变 的。
4.匿名内部类中使用的外部局部变量为什么只能是final变量?
5.关于final参数的问题
使用final修饰方法参数的目的是 防止修改这个参数的值 ,同时也是一种 声明和约定 ,强调这个参数是不可变的
原因在于java采用的 是值传递 【 这个话题很受争议 】,对于引用变量,传递的是引用的值【准确讲是内存里的地址】,
也就是说让 实参 和 形参 同时 指向了同一个对象 ,
因此让形参重新指向另一个对象对实参并没有任何影响。
这里的buffer.append操作的地址跟实参是同一个,所以结果是hello world.
如果方法changeValue里,buffer=new StringBuffer(“程序汪汪”);这里只能改变形参的地址,但不能改变实参的地址,所以打印结果是外面的 hello【 这地方很容易翻车 】
最后输出的还是 hello world
实参和形参【科普】
1、形参变量只有在 被调用时才分配内存单元 ,在调用结束时,就会释放出所分配的内存单元。所以,形参只能在函数内部才有效;【 生存周期在方法内 】
2、实参是:常量、变量、表达式、函数等,实参是何种类型的量,当开始在进行函数调用时,都必须有确定的值;【实参复杂值给形参】
3、在一般传值调用的机制中只能把实参传送给形参,因此在函数调用过程中,形参值发生改变,而实参中的值不会变化。【 很重要 】
参考文章