final修饰符

final可以修饰变量:被final修饰的变量被赋初值之后,不能对它重新复制。

final可以修饰方法,被final修饰的方法不能被重写。

final可以修饰类,被final修饰的类不能派生子类。

被final修饰的变量必须显式指定初始值,而且只能在如下3个位置指定初始值:

  1),定义final实例变量的时候指定;

  2),在非静态初始化块中为final实例变量指定初始值;

  3),在构造器中为final实例变量指定初始值。

public class FinalInstanceTest {

    final int var1 ="crazy Java".length();
    final int var2;
    final int var3;
    {
        var2 ="abcesdgd".length();
    }
    
    public FinalInstanceTest()
    {
        this.var3 = "xxxxxy".length();
    }
    
    public static void main(String[] args)
    {
        FinalInstanceTest fiv = new FinalInstanceTest();
        System.out.println(fiv.var1);
        System.out.println(fiv.var2);
        System.out.println(fiv.var3);
    }
}

被final修饰的类变量只能在两个地方指定初始值:

  1),定义final类变量时指定;

  2),在静态初始化块中为final类变量进行初始化;

final static int var4 = 90;
final static int var5;

static
{
  var5 = 1000;
}

内部类中的局部变量:

如果程序需要在匿名内部类中使用局部变量,这个局部变量必须使用final修饰。

Java要求被内部类访问的局部变量都使用final修饰的原因:对于普通局部变量而言,它的作用域就是停留在该方法内,当方法执行结束,该局部变量也随之消失;但内部类则可能产生隐式的“闭包Closure”,闭包将使得局部变量脱离它所在的方法继续存在。

 1 import java.util.Arrays;
 2 
 3 public class FinalCommandTest {
 4 
 5     public int [] process (IntArrayProductor cmd, int length)
 6     {
 7         int [] result = new int[length];
 8         for(int i=0;i<length;i++)
 9         {
10             result[i] = cmd.product();
11         }
12         return result;
13     }
14     public static void main(String[] args)
15     {
16         FinalCommandTest ct = new FinalCommandTest();
17         final int seed =5;
18         int [] result = ct.process(new IntArrayProductor() {
19             
20             @Override
21             public int product() {
22                 // TODO Auto-generated method stub
23                 return (int) Math.round(Math.random()*seed);
24             }
25         }, 6);
26         System.out.println(Arrays.toString(result));
27     }
28     
29 }
30 
31 interface IntArrayProductor
32 {
33     int product();
34 }
View Code

局部变量脱离它所在方法继续存在的例子:

 1 public class ClosureTest {
 2 
 3     public static void main(String[] args)
 4     {
 5         final String str ="Java";
 6         new Thread(new Runnable()
 7         {
 8             public void run()
 9             {
10                 for(int i=0;i<100;i++)
11                 {
12                     System.out.println(str+" "+i);
13                     try
14                     {
15                         Thread.sleep(100);
16                     }
17                     catch (Exception e)
18                     {
19                         e.printStackTrace();
20                     }
21                 }
22             }
23         }).start();
24     }
25 }
View Code

在main方法中定义的str 对象,main方法的生命周期介绍之后,局部变量str的作用域也会随之结束,但只要新线程里的run方法没有执行完,匿名内部类的实例的生命周期就没有结束,将一直可以访问str局部变量的值。这就是内部类会扩大局部变量作用域的例子。

原文地址:https://www.cnblogs.com/happinessqi/p/3439638.html