java基础——2final不简单

        final——一个并不陌生的java关键字,修饰变变量(包括实例变量,类变量)、方法、类。下面一行很经常使用到的code:
public static final String BACE_INFO = "baseinfo";
        首先,先明确一下,
  1. final修饰的变量不能够从新赋值。
  2. final修饰的方法不能够被重写。
  3. final修饰的类不能够派生子类。
  4. final修饰的实例变量必须显式的指定初始值,而且只能在如下三个位置初始化。
public class FinalInstanceTest{
    //定义变量时初始化
    final int var1 = 2;
    final String var2;
    final double var3;

    //非静态初始化代码块
    {
        var2 = "吃饭睡觉打豆豆";
    }

    //构造器中初始化
    public FinalInstanceTest(){
        this.var3 = 3.14;
    }
}

可是本质上final实例变量的初始化都是在构造器中进行的。
    5. final修饰的类变量也必须在定义时或静态初始化块中显式初始化,而本质上都是在静态初始化块中进行的。

       咱们着重看如下final修饰的字符串,小伙伴们判断一下下面程序的输出结果 java

public static void main(String[] args) {
	String str1 = "javacode";
	String str2 = "java" + "code";
	System.out.println(str1 == str2);  ------------------A

	String str3 = "java";
	String str4 = "code";
	String str5 = str3 + str4;
	System.out.println(str1 == str5);  ------------------B
}



        先公布结果:A 处代码会输出true 而B处代码会输出false。
        先来研究下A处代码。有人会说明明是两个String对象怎么会输出true呢?java存在一个java字符串缓冲池,他会缓存全部使用过的字符串直接量。str1 = "javacode" 这里便会缓存javacode这个字符串对象,而str2 = "java" + "code";能够在编译时肯定str2为"javacode"因此系统自动将str2指向字符串缓存的"javacode"。因此str1和 str2指向同一个字符串对象。而B处的代码,str5不能再编译时肯定,系统就不会将str5指向缓存池中的"javacode",结果也就会输出false。
        那么什么是编译时肯定呢?我理解为变量的赋值中不访问普通变量,不调用方法,只是基本的算术运算表达式或字符串链接运算,这样的变量可以被系统编译时肯定。显然上述代码中str一、str2符合,而str5不符合。
如何将B处也输出true 呢?咱们用到了final关键字。
        修改代码以下
public static void main(String[] args) {
	String str1 = "javacode";
	String str2 = "java" + "code";
	System.out.println(str1 == str2);  ------------------A

	final String str3 = "java";
	final String str4 = "code";
	String str5 = str3 + str4;
	System.out.println(str1 == str5);  ------------------B
}
        这时B处将输出true。         事实上final修饰的变量已经成为一个直接替换量(这是我本身起的名字),当后续代码再次用到这个变量时,系统会自动将其替换成相应的值,所以 String str5 = str3 + str4;至关于 String str5 = "java"+"code";str5也就能够编译时肯定了。此外相对于实例变量而言,在定义时赋初始值,非静态初始化块中,构造器中赋初始值都是同样的,都将在构造器中执行,可是对于final变量只有在定义时赋初始值才会被直接替换。         另外关于final修饰的方法,主要强调在继承中存在的问题。被final修饰的方法子类不能重写,并且实际上子类也没法访问到父类中final修饰的方法。
相关文章
相关标签/搜索