Java入门系列之final

前言

在C#经典面试中掺杂过Java的final关键字,主要用于类不能被继承,在C#则是利用关键字seal修饰类为密封类,而在Java中的final关键字的具体用法包含C#中const、readonly、seal三者使用之和,本节咱们来聊聊Java的关键字final。面试

关键字final

经过final关键字修饰意为没法改变,在Java早期版本经过final能够改善性能或者提升效率,但现现在版本final已经无所谓性能,咱们只关注于在设计时应用final的具体场景,final关键字包含两层含义:其一,编译时常量不变,其二,运行时初始化值然后不被改变。这二者其实就是C#中的const和readonly关键字的使用。 final主要用于三种状况,修饰数据、方法、类,但本质上都是表示不可变,至于“不可变”的含义就看对应哪一种场景。固然加上static修饰符只是代表在内存中只保存一份数据,这里咱们就不作过多探讨。编程

数据

编译时常量和C#中概念一致,只不过C#用const修饰,同时对于变量的命名都是采用大写方式,单词与单词之间用下划线隔开,好比以下编译时常量安全

public final int VALUE_ONE = 1;

上述已经说过,final不单单只是对于编译时必须为常量,还能够用于运行时初始化时的值,好比经过随机函数生成值dom

public  static Random random = new Random();

public final int VALUE_ONE = random.nextInt(20);

这种运行时初始化值方式就是C#中的readonly,以下:函数

public static Random random = new Random();

public readonly int VALUE_ONE = random.Next(20);

对于C#中的readonly初始值,咱们知道除了在定义时赋值,也能够在构造函数中初始化值,如果再加上static,很显然必须在静态构造函数中初始化性能

class Program
{
    public readonly int VALUE_ONE;

    public Program()
    {
        VALUE_ONE = 1;
    }
}

final关键字一样也能达到上述使用readonly的效果,只不过在Java中称其为“空白final”,所谓空白final是指被声明为final但未给定初始值,可是不管何种状况,编译器必须确保在使用数据以前必须进行初始化学习

public class Main {

    public final int VALUE_ONE;

    public Main() {
        VALUE_ONE = 1;
    }
}

参数

不管是做为方法参数仍是做为初始化变量的修饰,咱们能够更改该参数里面的值,可是没法更改参数引用所指向的对象。以下示例为修饰初始化类变量,做为方法参数同理,这里再也不阐述。this

class Value {
    int i;

    public Value(int i) {
        this.i = i;
    }
}

public class FinalDemo {
    public final Value value = new Value(1);
}
public class Main {

    public static void main(String[] args) {

        FinalDemo finalDemo = new FinalDemo();

        //能够更改final参数里的值
        finalDemo.value.i = 2;

        //不能更改参数所指向的对象(编译报错)
        finalDemo.value = new Value(2);
    }
}

方法

final修饰方法是将方法进行锁定,以防止任何继承类修改它自己的含义,此意为用以标记该方法不能被覆盖(对于对象范围内)或隐藏,这为后续开发人员建立其方法所在类的子类没法覆盖其行为提供有力的保证。好比以下计数器则是一个很好的例子spa

public class Counter {
    private int counter = 0;

    public final int count() {
        return ++counter;
    }

    public final int reset() {
        return (counter = 0);
    }
}

可是咱们去掉上述count方法的修饰符,进行以下操做,很显然将破坏原始方法的行为,打印出结果为2设计

Counter c = new Counter() {
            public int count() {
                super.count();
                return super.count();
            }
        };
System.out.println(c.count());

若将整个类定义为final时,这说明此类将不会被继承和C#中seal修饰符一模一样,或出于安全考虑,或出于设计已肯定该类不会再作任何变更,不但愿该类有子类

public final class Counter {
}

//编译发生错误
class SubCounter extends Counter {
}

总结

本节咱们详细讲解了final关键字,该关键字是C#中const、readonly、seal三者使用的组合,Java编程思想虽然将其划分为数据、方法、类,这里我认为划分为变量(包含数据和参数)、方法、类更合理。其实语法都大同小异,仍是那句话,学习的本质在于概括总结并触类旁通从而内化。 

相关文章
相关标签/搜索