final关键字的一些思考

来源:互联网 发布:周琦和姚明cba数据 编辑:程序博客网 时间:2024/06/01 07:18

final关键字在面试时是一个非常频繁的问题,对它的理解一定程度上可以反应出面试者的基础和对技术的钻研能力,下面从基础使用到帝城虚拟机来看一下final的相关内容。

1.final修饰的class(类)不能被继承;
2.final修饰的方法不能被重写,String就是被final修饰的;
3.被final修饰的变量不可以被改变(重点)
此处变量需要根据引用分类:

形如final a = 12引用不可变值,这种不必多说,不可变

final int a = 12;a = 13;//此处报错:“The final local variable fs cannot be assigned”。

形如 final Object a = new Object()引用对象

package com.xue;public class FinalString {    private String finStr;    public FinalString(String finStr) {        this.finStr = finStr;    }    public void setFinStr(String finStr) {        this.finStr = finStr;    }    public String getFinStr() {        return finStr;    }    @Override    public String toString() {        return super.toString();    }}
final FinalString s = new FinalString("12");final FinalString ss = new FinalString("aaa");s = ss;//此处报错:“The final local variable fs cannot be assigned”。s.setFinStr("123");System.out.println(s.getFinStr());//正确输出

对象里面的内容可以改变,但是引用指向的地址不能被改变

System.out.println(s.hashCode());//1s.setFinStr("123");System.out.println(s.hashCode());//和第一行输出时一样的,地址相同System.out.println(ss.hashCode());
/**         * final 修饰数组         * 用final修饰数组是没有意义的         */        String[] str1 = {"123", "234"};        final String[] str2 = {"345", "456"};         str1 = str2;//把Str2的内容赋给Str1也就是地址改变        System.out.println(str1.hashCode());        System.out.println(str2.hashCode());        str1[1] = "aaa";        System.out.println(str1.hashCode());

1、被final修饰的方法,JVM会尝试为之寻求内联,这对于提升Java的效率是非常重要的。因此,假如能确定方法不会被继承,那么尽量将方法定义为final的。

public final int getA(){    getA()语句1;    getA()语句2;    getA()语句3;    getA()语句4;    getA()语句5}
public static void main(String[] args){    main语句1;    main语句2;    int i = getA();    main语句3;    main语句4}

内联后却少了保护现场、恢复线程、建立栈帧等一系列的工作

public static void main(String[] args){    main语句1;    main语句2;    getA()语句1;    getA()语句2;    getA()语句3;    getA()语句4;    getA()语句5;    main语句3;    main语句4}

java语言因为多态的原因,只有在运行期间根据实际需要决定使用哪个实际的子类,这样非常灵活,但是这样导致在编译期间无法内联,因为不知道使用哪个方法,final关键字修饰的方法无法被重写,所以运行期间使用的方法在编译时必然是可以内联的。

2、被final修饰的常量,在编译阶段会存入调用类的常量池中,与实际定义这个常量的类没有关系

public class ConstClass{    public static final String HELLOWORLD =  "Hello World";    static    {        System.out.println("ConstCLass init");    }}public class TestMain{    public static void main(String[] args)    {        System.out.println(ConstClass.HELLOWORLD);    }}
原创粉丝点击