1. 说明
  1. Java中的关键字final通常是指“这是无法改变的”。一般使用final关键字有四种情况:变量、参数、方法、类。本文从这四个方面讲述final的用法。
  2. 参考资料《Java编程思想》。
  1. 例子
  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 }
  1. View Code
  2. 分析
  1. main的final修饰的变量a在定义的时候就初始化了,编译时a的值就已经确定了,不能修改,否则报错。
  2. Dog类中final修饰的变量age在定义的时候没有初始化,因此在编译期间是无法确定值的,只有创建Dog对象调用其构造方法的时候才可以确定。但是一旦初始化就不可更改,因此setAge方法和ff方法都试图再次对其赋值是错误的。 
  1. 结论
  1. final修饰基本类型变量,不论是在定义时初始化,还是通过构造方法初始化,一旦初始化之后就不可更改
  2. 另外,如果一个变量同时被final和static修饰,一般用大写表示,使用下划线分隔单词。
  1. 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 }
  1. 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 }
  1. View Code
  2. 运行结果如下图

java final 局部变量 java的final变量_System

  1. 分析
  1. 形象的说就是,我买了个猫放在家里,并给他起名为大黄,这时,我们可以知道这个猫在我家(地址是xxx市xxx区xxx街道),猫的名字叫大黄。然后我把猫的名字改为“老铁”,这时这个猫依然在我家(地址是xxx市xxx区xxx街道),但是名字却变了。名字变了还是我家的猫啊,我还是它的铲屎官啊。
  2. 从上面的截图也可以看出,c1变量虽然被final修饰了,但是依然可以改变c1所引用的对象(name改了)。
  3. 上面截图的@后面的东西是c1变量在内存中的地址,可以看出改变名字前后,c1的引用的地址没变。
  1. 结论
  1. final修饰引用类型变量表示这个变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变(如某个属性的值)。
  1. 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 }
  1. View Code
  2. 分析
  1. print1方法的参数age是被final修饰的基本类型,通过上面的代码可以看出,当我们在方法中试图再次对其赋值时,报错。说明final修饰基本类型参数表示这个参数在该方法中不可以修改。
  2. print2方法的参数c是被final修饰的引用类型,通过上面的代码可以看出,当我们在方法中试图再次对其赋值时,也报错。但是我们却可以设置c的名字。说明final修饰引用类型的参数表示在方法中这个参数的引用不可改变,但是这个对象可以改变。 
  1. 结论
  1. final修饰基本类型参数表示这个参数在该方法中不可以修改,就是不能再次赋值
  2. final修饰引用类型参数表示在方法中这个参数的引用不可改变,但是这个对象可以改变。  
  1. 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 }
  1. 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修饰的方法。
  1. 结论
  1. 当final修饰一个方法时,该方法不能被子类重写,但是子类可以使用父类的这个方法。
  2. 当final修饰一个方法时,本类可以重载被final修饰的方法。
  1. 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 }
  1. View Code
  2. 分析
  1. Person类是一个被final修饰的类,Student类打算继承Person类,但是报错,说明被final修饰的被不能被继承,当然方法也不能重写(不继承怎么重写)。
  2. print()方法显示创建一个Person对象,且name是jack,然后修改name为yaya,没有错误。说明被final修饰的类的成员变量是可以修改的。
  1. 结论 
  1. 当final修饰一个类时,这个类不能被继承,但是其成员变量可以被修改。     
  1. 总结
  1. final修饰变量
  1. final修饰基本类型变量,则该变量一个被初始化就不可被修改。
  2. final修饰引用类型变量,则该变量的引用不可被更改,但是该引用指向的对象可以被修改。 
  1. final修饰参数
  1. final修饰的参数是基本类型,则该参数在方法中不可被修改。
  2. final修饰的参数是引用类型,则该参数引用不可被修改,但是该引用指向的对象可以被修改。 
  1. final修饰方法
  1. final修饰的方法不可以被子类重写,但是子类可以使用这个方法。
  2. final修饰的方法可以被重载
  1. fianl修饰类
  1. final修饰的类不可以被继承,但是其成员变量可以被修改