Java中final关键字

来源:互联网 发布:linux 系统文件夹 编辑:程序博客网 时间:2024/05/16 07:01

浅析Java中的final关键字


一、final关键字的基本用法

final关键字可用来修饰类、方法和变量(包括成员变量和局部变量);

1 修饰类

final类表明该类不能被继承;

final类中的成员变量可根据需要设置为final,但final类中的所有成员方法都会被隐式地指定为final方法;


2 修饰方法

final方法表明继承于所在类的子类不能覆盖该方法;

注意:类的private方法会隐式地指定为final方法;


3 修饰变量

final变量若是基本数据类型,则其数值一旦在初始化后就不能修改;若是引用类型,则对其初始化后就不能再指向另一个对象;


二、深入了解final关键字

1 类的final变量和普通变量的区别?

final成员变量必须在定义时或构造器中进行初始化赋值,final局部变量必须在使用前初始化赋值,且final变量一旦被赋值就不能再被赋值;

举例1:

public class Test {    public static void main(String[] args)  {        String a = "hello2";         final String b = "hello";        String d = "hello";        String c = b + 2;         String e = d + 2;        System.out.println((a == c));        System.out.println((a == e));    }}

输出:

true, false

分析:

当final变量是基本数据类型或String类型时,若在编译期间就能确定其值,则编译器会将其当作编译期常量使用,即使用该final变量的地方相当于直接访问这个常量,不需要运行时确定;

因此上述代码中,由于变量b被final修饰,因此会被当做编译器常量,所以在使用到b的地方会直接将变量b 替换为它的 值,对于变量d的访问却需要在运行时通过链接来进行;

注意:只有在编译期间能确切知道final变量值的情况下,编译器才会进行这样的优化,如下面代码不会进行优化:

public class Test {    public static void main(String[] args)  {        String a = "hello2";         final String b = getHello();        String c = b + 2;         System.out.println((a == c));    }    public static String getHello() {        return "hello";    }}


2 被final修饰的引用变量指向的对象内容可变吗?

public class Test {    public static void main(String[] args)  {        final MyClass myClass = new MyClass();        System.out.println(++myClass.i);    }}class MyClass {    public int i = 0;}

输出:

1

分析:

引用变量被final修饰之后,虽然不能再指向其他对象,但是它指向的对象的内容是可变的;


3 final和static

public class Test {    public static void main(String[] args)  {        MyClass myClass1 = new MyClass();        MyClass myClass2 = new MyClass();        System.out.println(myClass1.i);        System.out.println(myClass1.j);        System.out.println(myClass2.i);        System.out.println(myClass2.j);    }}class MyClass {    public final double i = Math.random();    public static double j = Math.random();}

输出:

两个j值相同,两个i值不同;

分析:

static作用于成员变量用来表示只保存一份副本,而final的作用是用来保证变量不可变;


4 局部内部类为什么只能访问所在方法的final局部变量?

局部内部类是该类位于一个方法中;

局部内部类可访问局部变量,但局部内部类和局部变量的生命周期不同,即局部变量所在的方法执行结束就释放,但内部类对象若还有引用指向,方法执行结束仍存在,因此局部内部类就无法访问局部变量;Java采用复制的方法解决该问题;

若某一个变量的值在编译期见确定,则编译器默认在局部内部类的常量池中添加一个内容相同的字面量,因此局部内部类使用的是另一个局部变量,和方法中的局部变量完全独立;为防止修改另一个局部变量导致数据不一致,Java限定局部变量是final的,即不允许对其修改;

import java.util.ArrayList;import java.util.Collections;import java.util.Scanner;public class  Main{    public static void main(String[] args) {    A a = new A();    a.test();    }}class A{public void test(){int num = 20; // 添加final关键字即可class B{public void show(){System.out.println(num); // Java8之前,编译不通过}}B b = new B();b.show();}}




注明:此文章是转载海子的博文,详情见:http://www.cnblogs.com/dolphin0520/p/3736238.html


0 0
原创粉丝点击