Java_final修饰符总结

来源:互联网 发布:js append 编辑:程序博客网 时间:2024/06/13 12:35

final修饰符:

类变量:1.在声明该变量时指定初始值。2.在静态初始块中指定初始值。只能在这两个地方其中之一指定。

实例变量:1.声明该实例变量时指定初始值。2.在非静态初始化块中指定初始值。3.在构造函数中指定初始值。必须在这三个地方指定初始值。

 

只能在初始化块或静态初始化块赋值,不能再初始化块或静态初始化块中声明,因为在初始化块或静态初始化块中声明相当于局部变量。

 

都不能在普通方法中为final修饰的成员变量赋值。

 

final 修饰的成员变量必须显式的指定初始值,系统不会对final成员进行隐式的初始化。

不能对final修饰的形参重新赋值

 

final修饰的基本类型变量,不能对基本类型变量重新赋值。但是final修饰的引用类型变量。它保存的知识一个引用,final只保证这个引用类型变量所引起的地址不会改变,即一直指向同一个对象,但这个对象可以发生改变。

final修饰的引用类型变量不能够重新赋值,但是可以改变这个引用类型变量所指的对象的内容。

宏替换

对一个final变量来说,不管是类变量还是实例变量还是局部变量,只要改变量满足三个条件,这个final变量就不再是一个变量,而是相当于一个直接量。
1. 使用final修饰符修饰。
2. 在定义该final变量时指定了初始值。
3. 该初始值在编译时就确定下来。


package learnJava;import java.util.Arrays;public class FinalTest {public int age;final static int q=61;final static String dstr;final float er;final String str12;{final int a=12;//同样是final局部变量,不能通过对象访问。str12="ljkkj";System.out.println("初始化块"+a);}static {final double w4=3.3;//这里的w4是局部final变量,System.out.println("静态初始化块"+w4);dstr="jiki";//final static int h=12;//不能够在static块中定义类变量}public FinalTest(int age) {this.age=age;er=2.2f;System.out.println("构造函数"+er);}public void test(final int a){//a=2;//错误,不能对final修饰的形参进行赋值}public static void main(String[] args) {FinalTest dsd=new FinalTest(12);//System.out.println(dsd.a); 出错//System.out.println(dsd.w4); 出错System.out.println(dsd.str12);System.out.println(FinalTest.dstr);System.out.println("-----final基本类型变量和引用类型变量------");final int[] arr= {12,23,4,45};System.out.println(Arrays.toString(arr));//12 23 4 45arr[0]=11;System.out.println(Arrays.toString(arr));//11 23 4 45Arrays.sort(arr);System.out.println(Arrays.toString(arr));//4 11 23 45//arr=null;//arr= {1,23};都是非法的不能重新赋值。final FinalTest ft=new FinalTest(100);//是因为新对象会执行System.out.println(ft.age);ft.age=101;System.out.println(ft.age);//ft=null;非法System.out.println("-----可执行宏替换的final变量----");String s1="hello";final String s1_="hello";String s2="world";final String s2_="world";String s3="helloworld";String s4=s1+s2;String s4_=s1_+s2_;System.out.println(s3==s4);//falseSystem.out.println(s3==s4_);//true//因为s4还是引用不是常量,不能够在编译时就确定下来,而s1、s2、s3都是常量在编译就直接确定下来,在常量池中。//要解决这个问题可以直接将s1与s2进行宏替换,即加上final,这样s4在编译就能够确定。//宏替换必须在声明该变量的时候加上final赋初值}}

输出结果:

静态初始化块3.3
初始化块12
构造函数2.2
ljkkj
jiki
-----final基本类型变量和引用类型变量------
[12, 23, 4, 45]
[11, 23, 4, 45]
[4, 11, 23, 45]
初始化块12
构造函数2.2
100
101
-----可执行宏替换的final变量----
false
true


final方法

final修饰的方法不可以被重写,不希望子类重写父类的方法。(如getClass()方法)

对于private final 修饰的方法,因为它仅在当前类中出现,子类无法访问该方法,因此在子类中定义了一个和父类相同名、相同返回类型、相同形参列表的方方法,依然编译成果,因为子类不是重写了父类的privat final方法,只是重新定义了一个方法。

final方法不能够被子类重写,但是可以添加形参重载。

public class FianlMethod {public final void test() {}private final void train() {}public final void test(String arg) {}//编译成功}class Sub extends FianlMethod{//public void test() {} 编译错误public void train() {} //编译成功}


final类

final修饰的类不可以有子类,如java.lang.Math类就是一个final类,它不可以有子类。