百木园-与人分享,
就是让自己快乐。

Java中final的使用

原文链接https://www.cnblogs.com/dolphin0520/p/10651845.html

作者Matrix海 子

本文为笔记

0. 概述

final和static一样都是修饰词,final用来修饰类、方法、变量(包括局部变量和成员变量)。

1. final修饰类

被final修饰的类表示不可被继承,并且此时该类中的所有成员方法都会被隐式地修饰为final。

一般不把类定义为final类。

2. final修饰方法

说明这种方法提供的功能已经满足当前要求,不需要进行扩展,并且也不允许任何从此类继承的类来重写这种方法。

但是继承仍然可以继承这个方法,也就是说可以直接使用被final修饰的方法。在声明类中,一个 final 方法只被实现一次。

也就是只有明确不想被覆盖的方法会被修饰为final。

类的private方法会隐式地被指定为final方法

3. final修饰变量

  • 如果被修饰的变量是基本数据类型,则这个变量的值不会被改变。
  • 如果被修饰的变量是引用类型,则这个变量初始化后无法指向其他对象,但是指向的对象的值可以发生改变

3.1 final修饰成员变量

final修饰成员变量时,必须要保证该成员变量在被声明时或者构造器中就被赋值了,且一旦初始化完成,值就不能被改变了。

有如下代码

public class Test {
    public static void main(String[] args)  {
        String a = \"hello2\"; 
        final String b = \"hello\";
        String d = \"hello\";
        String c = b + 2; 
        String e = d + 2;
        System.out.println((a == c));
        System.out.println((a == e));
    }
}
/*
    true
    false
*/

此处的结果蕴含着final的特点:当final修饰基本数据类型和String时,如果在编译器就能知道这个变量的值,则编译器会把它当做编译期常量使用,类似C中的宏。于是此时的a和c实际指向了同一个引用,而e指向的是一块新的引用。

但是这个特性实现的前提是在编译期间就能知道具体的值,而如下所示

public class Test {
    public static void main(String[] args)  {
        String a = \"hello2\"; 
        final String b = getHello();
        String c = b + 2; 
        System.out.println((a == c));
    }

    public static String getHello() {
        return \"hello\";
    }
}
// false

上述代码在程序实际运行时,b才能通过调用getHello函数从而被初始化,所以无法在编译期间就获取到值,因此结果为false。

3.2 final修饰局部变量

注意Java中采用的是值传递,所以在调用时要注意。例如

public class Test {
    public static void main(String[] args)  {
        MyClass myClass = new MyClass();
        int i = 0;
        myClass.changeValue(i);
    }
}

class MyClass {
    void changeValue(int i) {
        i++;
    }
}
//Error

上述代码会报错,因为在changeValue函数体中,i被识别为局部变量。而该变量为final,无法改变i的值。

4. final和static

修饰成员变量时,final保证不可变,static表示每个对象都有一份副本。

public class Test {
    public static void main(String[] args)  {
        MyClass myClass1 = new MyClass();
        MyClass myClass2 = new MyClass();
        System.out.println(myClass1.i);
        System.out.println(myClass1.j);
        System.out.println(myClass2.i);
        System.out.println(myClass2.j);
    }
}

class MyClass {
    public final double i = Math.random();
    public static double j = Math.random();
}
// myClass1.i != myClass2.i
// myClass1.j == myClass2.j

i被修饰为final,表示不可变,而j表示所有对象共享同一个j,所以i不同,j相同。


来源:https://www.cnblogs.com/cayman98/p/15987807.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » Java中final的使用

相关推荐

  • 暂无文章