final关键字

final关键字的引入:

由于在继承中,方法有一个现象:方法重写

所以,父类的功能就会被子类给覆盖掉

但是,有些时候,我们不想让子类覆盖掉父类的功能,只让他使用

这个时候,针对这种情况,Java就提供了一个关键字:final

 举例:

 1 class Fu {
 2   public void show() {
 3       System.out.println("hello Fu");
 4   }
 5 }
 6 class Zi extends Fu {
 7     public void show() {
 8         System.out.println("hello Zi");
 9     }
10 }
11 public class FinalTest {
12     public static void main(String[] args) {
13         Zi zi = new Zi();
14         zi.show();
15     }
16 }

输出:

hello Zi

 

案例2:

 1 class Fu {
 2     public final void show() {
 3       System.out.println("hello Fu");
 4   }
 5 }
 6 class Zi extends Fu {
 7     //编译报错,Zi中的show无法覆盖Fu中的show,被覆盖的方法为final
 8     public void show() {
 9         System.out.println("hello Zi");
10     }
11 }
12 public class FinalTest {
13     public static void main(String[] args) {
14         Zi zi = new Zi();
15         zi.show();
16     }
17 }

 

final关键字的特点:

  final可以修饰:类,方法,变量

    被final修饰的类,不能被任何类继承

    

 1 final class Fu {
 2     public void show() {
 3       System.out.println("hello Fu");
 4   }
 5 }
 6 class Zi extends Fu { //编译报错,无法从最终Fu进行继承
 7     public void show() {
 8         System.out.println("hello Zi");
 9     }
10 }
11 public class FinalTest {
12     public static void main(String[] args) {
13         Zi zi = new Zi();
14         zi.show();
15     }
16 }

 

    被final修饰的方法是不能被重写的(见案例2)

    

    被final修饰的变量是不能被重新赋值

      此时的变量相当于常量(自定义常量) public final int num2 = 20;

      常量分为:字面值常量和自定义常量

 1 class Fu {
 2     public int num = 10;
 3     public final int num2 = 20;
 4 }
 5 class Zi extends Fu {
 6     public void show() {
 7         System.out.println(num);
 8         System.out.println(num2);
 9 
10         num = 100;
11         num2 = 200; //编译时报错,无法为最终变量num2分配值
12         System.out.println(num);
13         System.out.println(num2);
14     }
15 }

 

      

final关键字修饰局部变量:

  1. 权限修饰符修饰变量是没有意义的,因为局部变量本身就是被封装到方法中,外界无法访问的,但是final却可以修饰局部变量。

之前讲解的是final修饰成员变量的情况,那么final修饰局部变量是什么情况呢?

  1.在方法内部,该变量不可以被改变

    当局部变量是基本数据类型的时候,值不能被改变

    当局部变量是引用数据类型的时候,指的是地址值不能被改变,在堆内存中存放的值是可以被改变的

 案例4

 1 public static void main(String[] args) {
 2         //局部变量是基本数据类型
 3         int num = 10;
 4         final int num2 = 20;
 5 
 6         System.out.println(num);
 7         System.out.println(num2);
 8 
 9         num = 100;
10         //num2 = 200; //编译时报错,无法为最终变量num2分配值
11         System.out.println(num);
12         System.out.println(num2);
13     }

 输出:

10
20
100
20
class Fu {
    int age = 10;
}

public class FinalTest {
    public static void main(String[] args) {

        //局部变量是引用数据类型
        Fu fu = new Fu();
        System.out.println(fu.age);

        fu.age = 100;
        System.out.println(fu.age);

        final Fu fu2 = new Fu();
        System.out.println(fu2.age);

        fu2.age = 300;
        System.out.println(fu2.age);

    }
}

输出:

10
100
10
300

 案例5

 1 class Fu {
 2     int age = 10;
 3 }
 4 
 5 public class FinalTest {
 6     public static void main(String[] args) {
 7 
 8         Fu fu = new Fu();
 9         System.out.println(fu.age); //10
10 
11         Fu fu2 = new Fu();
12         fu2.age = 50;
13         System.out.println(fu2.age); //50
14         
15         fu = fu2;
16         System.out.println(fu.age); //50
17 
18     }
19 }

输出结果:

10
50
50

案例6

 1 public static void main(String[] args) {
 2         final Fu fu = new Fu();
 3         System.out.println(fu.age); //10
 4 
 5         Fu fu2 = new Fu();
 6         fu2.age = 50;
 7         System.out.println(fu2.age); //50
 8 
 9         fu = fu2; //编译时报错,无法为最终变量fu分配值
10         System.out.println(fu.age); 
11     }

 

final修饰变量的初始化时机

  1. 被final修饰的变量只能被赋值一次(不包括系统给出的默认值)

  2.在构造方法完毕前(针对非静态常量)

 

变量在初始化时先进行成员变量初始化,再进行构造方法初始化

//变量初始化时,先进行局部变量初始化,再进行成员变量初始化
class Fu {
    int num = 100;

    public Fu(){
        num = 200;
    }
}

public class FinalTest {
    public static void main(String[] args) {

        Fu fu = new Fu();
        System.out.println(fu.num); //200
    }
}

 

输出:

200

   final修饰变量的初始化时机:在对象构造完毕前即可。

1 class Fu {
2     final int num = 100;
3 
4     public Fu(){
5         num = 200; //编译时报错,无法为最终变量num分配值
6     }
7 }

 

 

class Fu {
    final int num;//此时只有系统给出的默认值

    public Fu(){
        num = 200; 
    }
}

public class FinalTest {
    public static void main(String[] args) {
        Fu fu = new Fu();
        System.out.println(fu.num); //200
    }
}

 

输出:

200

 

 

class Fu {
    final int num; 

    {
        num = 500; //先走构造代码块赋值,再走构造方法赋值
    }
    
    public Fu(){
        num = 200; //编译时报错,无法为最终变量num分配值
    }
}

 

posted @ 2017-04-14 15:47  bbxnhm  阅读(254)  评论(0编辑  收藏  举报