final关键字的一些思考

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());//1
s.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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值