Final浅谈
Final可以修饰类,也可以修饰方法和变量,还可以修饰参数,接下来就浅谈下Final的意义:
1、修饰类
被Final 修饰的类是不能被继承的,默认final修饰的类的方法也是final类型的。从字面就可以看出,final意为“最终的,不可更改的”,在用final修饰类之前,要确认是否该类永远都不要被继承,又或是出于安全的考虑;
2、修饰方法
被final修饰的方法不能被子类重写,但存在一种情况:父类的final方法是private,这样子类可以有同样的方法,但要清楚,这是两个单独的方法,并非重写;
例:
public class FinalTest {
private final void getName(){
System.out.println("苏东坡");
}
}
public class FinalTest2 extends FinalTest {
private void getName(){
System.out.println("佛印");
}
public static void main(String[] args) {
FinalTest2 t2=new FinalTest2();
t2.getName();
}
}
这两个getName方法其实是两个不同的方法,最后输出的结果是“佛印”。
3、修饰变量
被final修饰的变量要么在申明的时候就赋值,要么在类的构造方法中赋值,一旦赋值就不可更改
final修饰的变量和普通变量的区别:
public static void main(String[] args) {
String a="hello2";
final String b="hello";
String c="hello";
String d=b+2;
String e=c+2;
System.out.println(a==d);
System.out.println(a==e);
}
输出的结果是true,false;为什么呢,当final变量是基本数据类型和String类型,在编译期就已经i确认变量的值,所以编译器会把它当做编译期常量来用,等到运行时取的是对应的值,而普通变量需要在运行时通过链接来进行。但是只有在编译期确切知道值的变量,编译器才会做这样的优化,如果只有在运行时才能确认值,即使是final修饰的变量也没有这样的效果,如:
public static void main(String[] args) {
FinalTest2 t2=new FinalTest2();
String a="hello2";
final String b=t2.getValue();
String c="hello";
String d=b+2;
String e=c+2;
System.out.println(a==d);
System.out.println(a==e);
}
public String getValue(){
return "hello";
}
这个输出结果是false,false.
final修饰的引用变量指向的对象不可变,但对象的内容可以改变,因为它指向的是对象的地址
4、修饰参数
被final修饰的参数,在方法中不能被修改,但参数里面的内容是可以改的:
public static void main(String[] args) {
FinalTest2 t2=new FinalTest2();
StringBuffer buffer=new StringBuffer("修改前的");
t2.changeValue(buffer);
System.out.println(buffer);
}
public void changeValue(final StringBuffer buffer){
buffer.append("修改后的");
System.out.println(buffer);
}
打印的结果是两次“修改前的修改后的”,另补充:java中采用的是值传递,也就是实参和形参指向的是同一个对象,对于基本数据类型变量,直接对变量的值作了拷贝,当形参指向另一个对象的时候,实参并没有改变;
public static void main(String[] args) {
FinalTest2 t2=new FinalTest2();
StringBuffer buffer=new StringBuffer("修改前的");
t2.changeValue(buffer);
System.out.println(buffer);
}
public void changeValue( StringBuffer buffer){
buffer=new StringBuffer("修改后的");
System.out.println(buffer);
}
这个打印结果是“修改后的,修改前的”;