JavaSE---final关键字

使用final的两个原因:设计和效率,这两个原因相差很多,导致final会被误用。

1. 在数据上使用final

向编译器告知一块数据是恒定不变的。
- - - 两种情况:
一个永不改变的编译时常量;
一个在运行时被初始化的值,而你不希望它被改变。

对于编译期常量这种情况,编译器可以将该常量代入任何可能用到的计算公式中,在编译时执行计算式,减轻了运行时的负担。

Java中,这类常量必须是基本数据类型,并且以关键字final表示,这个常量一定要进行初始化。
对对象引用运用final时,引用指向的对象无法改变,但是对象自身是可以被修改的,(同样适用数组,它也是对象)

注:一个既是static又是final的域只占一段不能改变的存储空间。

对象的情况:

public class Test2 {
    public int a = 0;
    public static void main(String[] args) {
        final Test2 test1 = new Test2();
        // test1的引用不可以指向test2
        Test2 test2 = new Test2();
        // test1 = test2; 编译时错误

        // 对象自身可以被改变
        System.out.println(test1.a); // 0
        test1.a = 2;
        System.out.println(test1.a); // 2
    }
}

数组的情况:

public class Test2 {
    public static void main(String[] args) {
        final int[] arr_int = { 1, 2, 3 };
        // arr_int数组元素可以改变
        // 123
        printArray(arr_int);
        arr_int[0] = 2;
        // 223
        printArray(arr_int);

        // arr_int的引用不可以指向arr_int_2
        int[] arr_int_2 = { 3, 2, 3 };
        // arr_int = arr_int_2;
    }
    // 打印数组
    public static void printArray(int[] arr) {
        for (int a : arr) {
            System.out.print(a);
        }
        System.out.println();
    }
}

注:
不能因为某个数据是final的就认为在编译时可以指导它的值,可以在运行时进行赋值。

Random ran = new Random(47);
final int a = ran.nextInt(20);
// 18
System.out.println(a);

2. 在方法参数上使用final

Java允许在参数列表中以声明的方式将参数指明为final。这说明无法在方法内部更改引用指向的对象

void test(final Test2 test) {
    // 不能更改引用指向
    // test = new Test2();
}

3. 在方法上使用final

第一个原因:
把方法锁定,以防任何继承类来修改它。
第二个原因:
效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。

注:
类中所有的private方法都隐式地指定为final的。

这一问题可能会导致你混淆:子类可以覆盖父类的方法。

下面的代码子类Child和父类Father有相同的方法:say()
“覆盖”只有在某方法是基类的接口的一部分时才会出现。如果某方法是private的,那它就不是基类的接口的一部分,它仅是一些隐藏于类中的程序代码。子类根本访问不到父类的say方法,所以只是子类和父类方法名相同罢了,子类只认为是自己特有的方法,而父类没有,子类中say方法就是一个新的方法,并没有覆盖父类的say方法。

public class Test2 {
    public static void main(String[] args) {
        Child child = new Child();
        child.say();
        Father fchild = child;
        // 不能调用该方法
        // fchild.say();
    }
}
class Father {
    private final void say() {
        System.out.println("Father");
    }
}
class Child extends Father {
    public final void say() {
        System.out.println("Child");
    }
}

4. 在类上使用final

final用在类上表示该类不允许被继承。
由于final类是禁止继承的,所以类中所有方法都隐式指定为final的。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值