对java final修饰符的一些理解

来源:互联网 发布:ios程序员烂大街 编辑:程序博客网 时间:2024/06/05 09:13

1.final成员变量

final修饰的成员变量必须由程序员显示地指定初始值

类变量

必须在静态初始化块或声明时指定初始值,只能二者选一

实例变量

必须在非静态初始化,声明时或构造器中指定初始值,只能三者选一

注意:不要在final成员变量未初始化时访问其值

class TestClass{    //定义final成员变量,为进行初始化,系统也不会对其进行默认初始化    final int a;    //非静态初始化块    {        //a为进行初始化,此处代码报错        //System.out.println("a = "+ a);        a = 1;        System.out.println("a = "+ a);    }    public static void main(String[] args){        new TestClass();    }}

2.final局部变量

可以在其声明时进行赋值,一旦赋值之后便不能再次更改其值
可以不在其声明时进行赋值,在后续代码中可以对其进行赋值,一旦赋值之后便不能再次更改其值

3.final修饰引用类型变量

final修饰引用类型变量,只能保证引用的地址不变,即只引用一个对象,但不能保证对象的内容不发生改变

class TestClass{    private int a;    public TestClass(){        a = 10;    }    public void seta(int a){        this.a = a;    }    public int geta(){        return a;    }    public static void main(String[] args){        final TestClass tc = new TestClass();        //更换引用对象,此处代码报错        //tc1 = new TestClass();        //输出:a = 10        System.out.println("a = "+ tc.geta());        //更改对象的内容,不报错        tc.seta(20);        //输出:a = 20        System.out.println("a = "+ tc.geta());    }}

4.可执行“宏替换”的final变量

当满足以下3个条件时,这个final变量不再是一个变量,而是相当于一个直接量,变量被当作“宏变量”处理

  • 使用final修饰符修饰
  • 在声明该final变量时指定初始值
  • 在编译阶段已经确定了变量的值
class TestClass{    public static void main(String []args){        final int a = 10;        System.out.println(a);    }}

上述a变量满足“宏变量”原则。a在编译阶段已经确定了值,执行 System.out.println(a); 代码时,实际转换为 System.out.println(10); 执行。

除了上述final变量被直接赋值的情况外,如果被赋的表达式只是基本的算数表达式或字符串连接运算,没有访问普通变量,调用方法,java编译器同样将会把这种final变量当成“宏变量”处理

final int a = 1 + 2;//a被当作“宏变量”final String str1 = "java" + "8"//str1被当作“宏变量”final String str2 = "java" + String.valueOf(8);//str2不是“宏变量”,因为str2初始化时调用了方法

5.final方法

final修饰的public方法子类不能被重写
对于父类中一个private方法,子类是不能继承的,所以也不存在重写,即子类中可以定义一个与其同名,同参,同返回值的方法,该方法是完全独立于父类的,只是定义了一个新方法,并不是重写

class BaseClass{    public final void show1(){        System.out.println("BaseClass:public final");    }    private final void show2(){        System.out.println("BaseClass:private final");    }}class SubClass extends BaseClass{    //final方法不能被子类重写,报错//  public final void show1(){//      System.out.println("SubClass:public final");//  }    //此方法虽然同名,同参,同返回值。但该方法是完全独立于父类的,只是定义了一个新方法,并不是重写    private final void show2(){        System.out.println("SubClass:public final");    }}

6.final类

final类不能被继承。例如java.lang.Math类是一个final类,不能被继承

参考:李刚《疯狂java讲义》(第2版)

0 0