Java基础(五) final关键字浅析

前面在讲解String时提到了final关键字,本文将对final关键字进行解析。html

staticfinal是两个咱们必须掌握的关键字。不一样于其余关键字,他们都有多种用法,并且在必定环境下使用,能够提升程序的运行性能,优化程序的结构。下面咱们来了解一下final关键字及其用法。app

final从整体上来讲是“不可变的”,可用于修改类、方法、变量。性能

一. final类

final修饰的类,该类不能被继承。当你确认一个类永远不会被继承或不想被继承,那么就能够用final修饰。优化

一样,对于接口(interface)和抽象类(abstract Class),其本就是为了“多态”而设计,天然没法用final关键字修饰ui

final类中的成员方法默认也被隐式指定为final方法。设计

二. final方法

final修饰的方法不可被重写。3d

例子:code

/**
 * 父类
 * @author LH
 */
public class FinalDemo1 {
    public final void test() {
        
    }
}

三. final变量

final变量包括成员变量和局部变量。变量类型包括基本数据类型、对象。htm

经过final修饰局部基本类型变量(及其包装类),数值一经初始化(能够定义时初始化,也能够在使用前初始化)不可改变。如:对象

final int a = 0;
a = 1;//报错
final int b;
b = 1;//编译经过

经过final修饰局部引用类型变量时,其引用的对象(内存地址)(能够定义时初始化,也能够在使用前初始化)不可改变,但对象中存放的数据能够改变

public static void main(String[] args) {
    final String str1 = "helloWorld";
    str1 = "helloChina";//编译出错,String的不可变性,此处返回的是新的对象引用。

    final StringBuilder sb = new StringBuilder("hello");
    sb.append("world");//编译经过

    sb = new StringBuilder("China");//编译出错
}

final修饰的成员变量必须在定义的时候直接初始化,不然会编译出错

public class FinalDemo1 {
    public final int age;//final修饰的基本类型,编译出错
    public final int age1 = 20;//final修饰的基本类型,编译经过
    public final StringBuilder address;// final修饰的引用类型,编译出错
    public final StringBuilder address1 = new StringBuilder("中国");//final修饰的引用类型,编译经过
}

那么final变量与普通变量之间到底有何区别,看下面的例子

public static void main(String[] args) {
    String str0 = "helloWorldChina";
    String str1 = "helloWorld";
    String str3 = str1 + "China";
    System.out.println(str0 == str3);//false
    
    final String str2 = "helloWorld";
    String str4 = str2 + "China";
    System.out.println(str0 == str4);//true
    
    final String str5;
    str5 = "helloWorld";
    String str6 = str5 + "China";
    System.out.println(str0 == str6);//false
}

str0 == str3运行结果为false,这是由于经过“+”生成了一个新的字符串对象,返回的引用地址和str0再也不同样,这在《Java基础(三) String深度解析》中有讲解。

那么str0 == str4的执行结果为何是true?

经过final修饰的变量,若是在编译期均可以知道确切值(定义变量的时候就初始化),那么在编译器会将其当作常量使用,全部用到该变量的地方就至关于直接使用该常量,String str4 = str2 + "China" 在编译期间都已经合并处理成String str4 = "helloWorldChina",所以str0与str4引用了常量池中同一个字符串字面量的地址,故而结果为true。

而str0 == str6的执行结果为false也很好理解

str5在编译期并不知道确切值,而是在使用以前才进行初始化,所以编译器没法事先进行合并处理,str6经过“+”生成了一个新的字符串对象,返回的引用地址和str0也再也不同样。

而针对基本数据类型来讲定义为final变量与普通变量,比较结果来讲并没有差别

public static void testint(){
    int int0 = 8;    
    final int int1;    
    int1 = 4;    
    int int2 = int1 + 4;    
    System.out.println(int2 == int0);//true
}

由于基本数据类型并不存在引用传递的概念,基本类型变量也是字面常量,因此对基本类型的操做都是直接对值的操做,和引用不同,比较的并不是地址。

四. 总结

本文主要对final关键字的原理进行了讲解,同时对其基本用法进行了说明,包括final修饰的类,final修饰的方法和final修饰的变量,另外文中String变量经过==比较只是为了更加清晰的说明final原理,实际应用场景比较的时候仍是用equals()方法,final也常常和static配合使用做为“全局常量”,如有不对之处,请批评指正,望共同进步,谢谢!

相关文章
相关标签/搜索