Java基础知识之final关键字

本文详细解析了Java中final关键字的使用方法,包括修饰变量、参数、方法和类的情况,并通过实例展示了final的不同应用场景。
  1. 说明
    1. Java中的关键字final通常是指“这是无法改变的”。一般使用final关键字有四种情况:变量、参数、方法、类。本文从这四个方面讲述final的用法。
    2. 参考资料《Java编程思想》。
  2. 例子
    1. final修饰变量
      1. final修饰基本类型变量
        1. 如果final修饰基本类型变量,则不能再对这个基本类型变量重新赋值,否则报错。
        2. 代码
           1 public class Test {
           2     public static void main(String[] args) {
           3         final int a = 11;
           4         int b = 111;
           5         a = 123;//The final local variable a cannot be assigned. It must be blank and not using a compound assignment
           6         a = b;//The final local variable a cannot be assigned. It must be blank and not using a compound assignment
           7         System.out.println(a);
           8     }
           9     
          10     class Dog{
          11         private final int age;
          12         
          13         public Dog(int age){
          14             this.age = age;
          15         }
          16 
          17         //The final local variable a cannot be assigned. It must be blank and not using a compound assignment
          18         public void setAge(int age){
          19             this.age = age;
          20         }
          21         //The final local variable a cannot be assigned. It must be blank and not using a compound assignment
          22         public void ff(){
          23             this.age = 12;
          24         }
          25     }
          26 }
          View Code
        3. 分析
          1. main的final修饰的变量a在定义的时候就初始化了,编译时a的值就已经确定了,不能修改,否则报错。
          2. Dog类中final修饰的变量age在定义的时候没有初始化,因此在编译期间是无法确定值的,只有创建Dog对象调用其构造方法的时候才可以确定。但是一旦初始化就不可更改,因此setAge方法和ff方法都试图再次对其赋值是错误的。 
        4. 结论
          1. final修饰基本类型变量,不论是在定义时初始化,还是通过构造方法初始化,一旦初始化之后就不可更改
          2. 另外,如果一个变量同时被final和static修饰,一般用大写表示,使用下划线分隔单词。
      2. final修饰引用类型变量
        1. 代码
          1. Cat类代码
             1 public class Cat {
             2 
             3     private String name;
             4 
             5     public String getName() {
             6         return name;
             7     }
             8 
             9     public void setName(String name) {
            10         this.name = name;
            11     }
            12 
            13     public Cat(String name) {
            14         super();
            15         this.name = name;
            16     }
            17 }
            View Code  
          2. Test类代码
             1 public class Test {
             2     public static void main(String[] args) {
             3         final Cat c1 = new Cat("大黄");
             4         System.out.println(c1.getName());
             5         System.out.println(c1);
             6         c1.setName("老铁");
             7         System.out.println(c1.getName());
             8         System.out.println(c1);
             9     }
            10 }
            View Code
          3. 运行结果如下图
        2. 分析
          1. 形象的说就是,我买了个猫放在家里,并给他起名为大黄,这时,我们可以知道这个猫在我家(地址是xxx市xxx区xxx街道),猫的名字叫大黄。然后我把猫的名字改为“老铁”,这时这个猫依然在我家(地址是xxx市xxx区xxx街道),但是名字却变了。名字变了还是我家的猫啊,我还是它的铲屎官啊。
          2. 从上面的截图也可以看出,c1变量虽然被final修饰了,但是依然可以改变c1所引用的对象(name改了)。
          3. 上面截图的@后面的东西是c1变量在内存中的地址,可以看出改变名字前后,c1的引用的地址没变。
        3. 结论
          1. final修饰引用类型变量表示这个变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变(如某个属性的值)。
    2. fianl修饰参数
      1. 测试类代码
         1 public class Test {
         2     public static void main(String[] args) {
         3         print1(11);
         4         Cat c = new Cat("大黄");
         5         print2(c);
         6     }
         7     
         8     static void print1(final int age){
         9         age = 11;//The final local variable age cannot be assigned. It must be blank and not using a compound assignment
        10         System.out.println(age);
        11     }
        12     
        13     static void print2(final Cat c){
        14         c = new Cat("haha");//The final local variable age cannot be assigned. It must be blank and not using a compound assignment
        15         c.setName("yaoyao");
        16     }
        17 }
        View Code
      2. 分析
        1. print1方法的参数age是被final修饰的基本类型,通过上面的代码可以看出,当我们在方法中试图再次对其赋值时,报错。说明final修饰基本类型参数表示这个参数在该方法中不可以修改。
        2. print2方法的参数c是被final修饰的引用类型,通过上面的代码可以看出,当我们在方法中试图再次对其赋值时,也报错。但是我们却可以设置c的名字。说明final修饰引用类型的参数表示在方法中这个参数的引用不可改变,但是这个对象可以改变。 
      3. 结论
        1. final修饰基本类型参数表示这个参数在该方法中不可以修改,就是不能再次赋值
        2. final修饰引用类型参数表示在方法中这个参数的引用不可改变,但是这个对象可以改变。  
    3. final修饰方法
      1. 代码
         1 public class Test {
         2     public static void main(String[] args) {
         3         
         4     }
         5     
         6     class Person{
         7         final void test(){
         8             System.out.println("别摸我");
         9         }
        10         
        11         void test(String name){
        12             System.out.println(name);
        13         }
        14     }
        15     
        16     class Student extends Person{
        17         //Cannot override the final method from Test.Person
        18         void test(){
        19             
        20         }
        21         
        22         void test(String name){
        23             System.out.println(name);
        24         }
        25         
        26         void print(){
        27             super.test();
        28         }
        29     }
        30 }
        View Code
      2. 分析
        1. Person是父类。Student继承了Person类,是子类。
        2. Person类有一个被final修饰的方法test(),还有一个重载方法test(String name),这两个方法都没有语法错误。
        3. Student类有一个test(String name)方法,重写了父类的test(String name)方法,没有问题。但是另一个方法test()重写父类的被final修饰的test()方法时,却报错了。说明被final修饰的方法不能被子类重写。另外print()方法中调用了父类Person中的被final修饰的test()方法,也没有问题,说明子类可以使用父类中被final修饰的方法。
      3. 结论
        1. 当final修饰一个方法时,该方法不能被子类重写,但是子类可以使用父类的这个方法
        2. 当final修饰一个方法时,本类可以重载被final修饰的方法
    4. final修饰类
      1. 代码
         1 public class Test {
         2     public static void main(String[] args) {
         3         print();
         4     }
         5     
         6     static void print(){
         7         Person p = new Person("jack");
         8         System.out.println(p.getName());
         9         p.setName("yaya");
        10         
        11         System.out.println(p.getName());
        12     }
        13     
        14 }
        15 
        16 final class Person{
        17     String name;
        18     
        19     public Person(String name) {
        20         super();
        21         this.name = name;
        22     }
        23 
        24     public String getName() {
        25         return name;
        26     }
        27 
        28     public void setName(String name) {
        29         this.name = name;
        30     }
        31 }
        32 
        33 //The type Student cannot subclass the final class Test.Person
        34 class Student extends Person{
        35     
        36 }
        View Code
      2. 分析
        1. Person类是一个被final修饰的类,Student类打算继承Person类,但是报错,说明被final修饰的被不能被继承,当然方法也不能重写(不继承怎么重写)。
        2. print()方法显示创建一个Person对象,且name是jack,然后修改name为yaya,没有错误。说明被final修饰的类的成员变量是可以修改的。
      3. 结论 
        1. 当final修饰一个类时,这个类不能被继承,但是其成员变量可以被修改。     
  3. 总结
    1. final修饰变量
      1. final修饰基本类型变量,则该变量一个被初始化就不可被修改。
      2. final修饰引用类型变量,则该变量的引用不可被更改,但是该引用指向的对象可以被修改。 
    2. final修饰参数
      1. final修饰的参数是基本类型,则该参数在方法中不可被修改。
      2. final修饰的参数是引用类型,则该参数引用不可被修改,但是该引用指向的对象可以被修改。 
    3. final修饰方法
      1. final修饰的方法不可以被子类重写,但是子类可以使用这个方法。
      2. final修饰的方法可以被重载
    4. fianl修饰类
      1. final修饰的类不可以被继承,但是其成员变量可以被修改

转载于:https://www.cnblogs.com/yanglz528/p/7834848.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值