《Java迷之知识点》之-----final关键字

1.final是啥

    final是个java的保留关键字,它的意思是,用了final来修饰,就表示它是不可变的。

    那么问题来了,“不可变”是什么东西????

    其实,对于变量,方法,类,final的“不可变”代表着不同的含义。

2.final用于变量上

    先看下面代码:

public class FinalTest {

    //final 数据必须初始化,要么在声明的时候,要么在构造的时候(构造方法里面)
    public final String name = "qwe";

    //final + static 必须在声明的时候初始化,表示这是一个静态常量(额外知识点)
    public static final String name2 = null;

    public static void main(String[] args) {

        FinalTest test = new FinalTest();
        //下面这句话编译器直接报错,因为它修改了name,准确的说是 name的引用
        //test.name = "asd";
    }

}

    当final去修饰变量时,代表着这个变量的引用地址不可变。什么是引用地址?我们知道在Java中String是不可变的,当我把 name 变量赋值为 asd 时,不是代表着 qwe 变成了 asd,而是jvm会先在内存中生成 asd,现在内存中有 qwe,asd 两个东西(不考虑GC),然后它会把name原来指向的内存地址(qwe的内存地址),指向新的内存地址(asd的内存地址)。那对于name来说,引用地址是不是发生变化了?而final修饰的变量,目的就是让name的内存地址不能变。所以这就是final对于变量的“不可变”。

    下面来思考另一个问题。假如我有Person类,它有个name属性:

class Person{

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

    非常简单,当我把Person 实例出一个 final对象时:

    public static void main(String[] args) {

        final Person person = new Person();
        person.setName("123");
        
    }

    以上代码会报错吗?答案是不会!为什么呢?我们先看看代码,首先final修饰的是 person 对象,person对象的“引用地址”变了吗?并没有,只是person的name属性的引用地址变了,而name又没有用final修饰,所以自然不会报错,但是下面的情况是会报错的:

final Person person = new Person(); 
//person = new Person(); //编译器报错,因为修改了它的引用

3.final用于方法上

    final用于方法上的意思就比较简单了,它意味着,子类不能重写父类的这个方法,看代码:

public class FinalTest {

    public final void say(String str){
        System.out.println("say " + str);
    }
}

class FinalSon extends FinalTest{

    //编译器报错,不能重写父类的final方法
    //public final void say(String s){}
}

    以上的例子很容易就说明了final对于类的作用,有时候我们会看到下面这样的代码:

public void say2(final String str){
    //编译器报错
    //str = "333";
}

    当我们理解了 final 作用于变量上的意义时,理解这个就非常简单了,final 用于变量上是什么意思?就是变量的“引用地址”不可变,所以上面的代码连编译器都通不过

4.final作用于类上

    final作用在类上面就更简单,它代表着这个类不能被继承,也有大家默认的一个意思(约定俗成):这个类的功能已经圆满了,不需要修改了。(是不需要,不是不能),看代码:

final class FinalF{

}


//编译器直接报错
class Final2 extends FinalF{

}

        简单粗暴,事实上,String类就是用final修饰的:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
  
   ....
}

5.总结

    至此,final终于搞清楚了,总之一句话---“不可变”,这也是final设计之初的意图。

转载于:https://my.oschina.net/u/3582320/blog/1499670

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值