我们从数据 方法 类 三个方面去讨论fianl关键字。 <br /> 7.8.1final数据<br /> 有时候我们需要通过final来告诉程序一个数据是不变的。在对象的引用被fianl修饰时,不变的是其引用也就是引用在栈中的存储空间,此时,这个引用就不能去问他指向另一个对象了。然而对象自身的属性是可以被修改的。
1.一个永远不变的编译时的常量2.在运行时初始化的值,我们不需要他去改变。
第一种情况:编译的常量必须是java所指的基本数据类型。而且要用fianl修饰,同时对这个常量进行定义的时候必须进行赋值。<br />第二种情况:运行时初始化的值,我们不需要去改变。对此我们需要用static和fianl一起去修饰。当一个域被static和fianl公共修饰时,他只是占据了一段不能被修改的存储空间。对于这种域我们常用大写来表示,并且用下划线去区分每个单词。<br /> 通过下面的这个列子我们来区分static fianl修饰的域和fianl修饰的域有何区别:
package com.zx.test07.test07_01;import java.util.Random;class Test {Test() {System.out.println("Test()");}}public class FianlAndStaticDemo {String name;public FianlAndStaticDemo(String s){name=s;}//1.static fianl 和 fianl 修饰的引用类型有何不同?static final Test TEST = new Test();final Test test1 = new Test();//2. static fianl 和 fianl 修饰的String类型有何不同?static final String STR_ONR="static final ";final String str_tow="final String";//3.static fianl 和fianl 修饰的基本类型有何不同?private static Random random=new Random(47);static final int SFI=random.nextInt();final int fi=random.nextInt();@Overridepublic String toString() {return name+" test的地址值:"+TEST +" "+"test1的地址值:"+test1+" "+"STR_ONR的值"+STR_ONR+" "+"str_tow的值"+str_tow+" "+"SFI的值"+SFI+" "+"fi的值"+fi;}public static void main(String[] args) {FianlAndStaticDemo fianlAndStaticDemo01 = new FianlAndStaticDemo("001");FianlAndStaticDemo fianlAndStaticDemo02 = new FianlAndStaticDemo("002");FianlAndStaticDemo fianlAndStaticDemo03 = new FianlAndStaticDemo("003");System.out.println(fianlAndStaticDemo01);System.out.println(fianlAndStaticDemo02);System.out.println(fianlAndStaticDemo03);}}//output:Test()Test()Test()Test()001 test的地址值:com.zx.test07.test07_01.Test@4554617c test1的地址值:com.zx.test07.test07_01.Test@74a14482 STR_ONR的值static final str_tow的值final String SFI的值-1172028779 fi的值1717241110002 test的地址值:com.zx.test07.test07_01.Test@4554617c test1的地址值:com.zx.test07.test07_01.Test@1540e19d STR_ONR的值static final str_tow的值final String SFI的值-1172028779 fi的值-2014573909003 test的地址值:com.zx.test07.test07_01.Test@4554617c test1的地址值:com.zx.test07.test07_01.Test@677327b6 STR_ONR的值static final str_tow的值final String SFI的值-1172028779 fi的值229403722
结论:<br /> 1.static和fianl修饰的引用变量只执行一次且不会开辟新的储存空间,而fianl修饰的变量会在每次创建新的是列时候被执行一次,且会为新的实例开辟新的存储空间<br /> 2.static和fianl修饰的String 类型是不变的也是只执行一次,而fianl修饰的String 类型也会在每次创建实例的时候执行(因为String类是被fianl修饰的)所以每次的值相同的。<br /> 3.static和fianl修饰的基本类型变量也只会执行一次,而fianl修饰的变量也会在每次创建实例的时候去执行。<br /> 扩展:我们能对staticfinal修饰的域进行修改,并且同一个对象的其他实例也可以可以感知,而且每一次新的修改都会覆盖上一个实例的修改。
package com.zx.test07.test07_01;class School{String s_name;School(){System.out.println("school");}public void setS_name(String s_name) {this.s_name = s_name;}public String getS_name() {return s_name;}}public class StaticDemo {static final School S=new School();@Overridepublic String toString() {return " "+S;}public static void main(String[] args) {StaticDemo staticDemo01= new StaticDemo();StaticDemo staticDemo02 = new StaticDemo();StaticDemo staticDemo03= new StaticDemo();staticDemo01.S.setS_name("小学");System.out.println(staticDemo01.S.getS_name());staticDemo02.S.setS_name("中学");System.out.println(staticDemo02.S.getS_name());staticDemo03.S.setS_name("高中");System.out.println(staticDemo03.S.getS_name());}}
空白fianl:指声明final但有未给定初始值的域。所以说只要是在构造器之前执行的域都可以为空白fianl初始化。
class Fianl{fianl int i;{//普通代码先构造器执行i=setInt();}int SetInt(){return 3;}}
2.fianl方法:
1.fianl修饰的方法,是无法被继承的,其中如果是private修饰的方法,无论是否有fianl修饰都是无法被继承的(从访问权限解释)
2.fianl修饰的方法参数是无法被修改的只能引用参数,final方法不是基类接口的一部分,对于扩展类来说,与基类final修饰的方法同名,仅仅是生成了一个新的方法,并没有覆盖基类的方法。
package com.zx.test07.test07_01;class Student{Student(){System.out.println("Student()");}public void test01(final String name){System.out.println("....");}private void test02{System.out.println(".....");}}public class FianlAndPrivate extends Student {@Overridepublic void test01(String name) {super.test01(name);}/** public void test01(String nam) {super.test01(name);} 这是错误的** */public static void main(String[] args) {FianlAndPrivate fianlAndPrivate = new FianlAndPrivate();// fianlAndPrivate.test02();不能调用父类的private 和fianl修饰的方法}}
fianl类:被fianl修饰的类是不能继承的,有于fianl类不能被继承,所以说fianl类中所有方法都是隐形定义为fianl的。但里面的域可以根据自己的选择去定义是否为fianl。
package com.zx.test07.test07_01;final class Student{final String name="高中";int i;Student(){System.out.println("Student()");}public void test01(final String name){System.out.println("....");}private void test02{System.out.println(".....");}}public class FianlAndPrivate extends Student {//是不能继承的,编译器会报错}
