java final关键字

java final关键字

final关键字的定义

java中final关键字一旦被赋值就无法改变。final关键字能修饰类和方法,变量(包括对象)。

final Person perso;
key = new Person("a");
key = new Person("b");【错误】 已经在上一步赋值了,final修饰的key不可以再赋值

不能改变是key对应"123"的引用不改变,对象里面的数据是可以改变。别误解。

  1. 用final修饰的变量不能被修改
  2. 用final修饰的类不能够被继承
  3. 用final修饰的方法不能被重写

所以用final修饰的变量,方法,类都是确定的。不会发生变化的。

String上的final陷阱

有一段代码如下:

public class Main {
    public static void main(String[] args) {
        final String finalStr = "1234";
        String normalStr = "1234";
        String testStr = "123400";

        String a = finalStr + "00";
        String b = normalStr + "00";

        System.out.println("r0 =" + (finalStr == normalStr));
        System.out.println("r1 =" + (a == testStr));
        System.out.println("r2 =" + (b == testStr));
    }
}

输出的结果是?

答案是:

r0 = true
r1 = true
r2 = false

解释之前需要说明java如何赋值对象的。

java对象一般都是存在堆上面,但是有一个例外就是String,为了减少频繁创建String的内存开销,设计者希望在定义一个字符串时,如何恰好曾有一个相同的,那么就使用这个已经存在的,于是java设计了常量池,因此String即可以像普通对象一样存在堆上,也能存在常量池上。

  • 直接用String a = “XXX”这种格式会存在常量池,实例化之前会找是否存在一个相同的(equal)的对象,有就直接赋值过来,没有就在常量池创建,因此String对象设计成无法修改里面的值的,如果要改值就得重新实例化对象。
  • 如果使用String a = new String(“xxx”)的方式,就会存储在堆上。这个也是其他对像的存储方式。
  • 如果就是 String a = b + “XXX”,这种方式。我们可以确定“xxx”存储在常量池里面,但是我们不能确定a是否也在,如果a是final修饰的,且是存在常量池(final String b = “123”),java会定义在常量池,其他情况在堆上。

分析上述代码:

  1. 赋值normalStr和finalStr java会在常量池中找,如果没有,就申请一个,所以normalStr与finalStr是一个对象,所以==,
  2. 对于finalStr,由于finalStr是确定的,因为用final修饰的变量不能被修改,java在拼接成“123400”后会在常量池中找,然后找到testStr,所以后面的a实际上就是testStr,类似于直接String a = “123400”
  3. 对于normalStr,normalStr不确定是在堆还是常量池上,因为normalStr可以在后面修改,可以再赋值一次,出于最安全考虑会在堆上创建对象

如有错误和疑问请指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值