final在java的作用当然不止是对变量的修饰,在这里简单的介绍一下final在java中的作用。

修饰类

表明该类不可被继承,类中的所有成员方法都隐式的被指定为final方法,成员变量则可以定义为final,也可以不定义为final;

修饰方法

用final修饰方法的原因有两个:

  1. 锁定这个方法,防止任何继承类修改它的含义;
  2. 提高效率:在方法前面添加final进行修饰可以提高效率,其原理是基于内联/内嵌(inline)机制,它会使你在调用final方法时,直接将方法的主体插入到调用处,从而省去调用函数所花费的开销。但是如果方法过于庞大或者其中有循环的话,这种提高效率的方法可能会失效。

修饰变量:

终于还是到这里了。

在java中,final对变量的修饰的作用,是防止变量值的改变;

  1. 如果修饰的是基本类型数据变量,则该变量的值不能发生改变;
  2. 如果修饰的是引用类型数据变量,则该变量不会内二次初始化;

解释:由于引用类型数据变量被初始化后,其值是一个地址,所以不会被二次初始化,则地址不改变。

特别备注:final对引用类型变量的修饰效果:

/**
     * 这是一个测试,证明final在修饰引用类型参数的时候能够保证参数不被二次初始化。
     * 
     * 过程: 
     * 1.定义一个自定义类变量test;
     * 2.定义一个String测试变量str; 
     * 3.定义一个String变量str2,用来测试str的地址是否改变;
     * 4.在初始化后进行一次test和str的地址输出; 
     * 5.在调用函数后再进行一次test和str的地址输出; 
     * 6.比较两次地址是否发生改变;
     * 
     * 解释:因为test和str都是引用类型变量,所以变量经过初始化后它们的值都是一个地址,
     *          因此只有地址没有改变,则可以证明该变量没有被二次初始化。
     *
     */
    public static void main(String args[]) {
        String str = "";
        MyTest Test = new FinallyTest().new MyTest();
        final String str2 = str;
 
        // 未调用函数前的地址
        System.out.println("调用函数前的test地址:" + Test);
        // 进行地址比较,因为无法直接获得str的地址,所以通过比较的方式证明str的地址没变。
        System.out.println("调用函数前的str地址:" + (str == str2));
 
        // 调用函数进行测试
        testClass(Test);
        testString(str);
 
        // 调用函数后的地址
        System.out.println("调用函数后的test地址:" + Test);
        System.out.println("调用函数后的str地址:" + (str == str2));
    }
    // final修饰MyTest
    public static void testClass(final MyTest test) {}
    
    // final修饰String
    public static void testString(final String str) {}
 
    public class MyTest {
        public void change(final String str) {}
        }

运行结果:

内容补充:

类的final变量和普通变量有什么区别?

  当用final作用于类的成员变量时,成员变量(注意是类的成员变量,局部变量只需要保证在使用之前被初始化赋值即可)必须在定义时或者构造器中进行初始化赋值,而且final变量一旦被初始化赋值之后,就不能再被赋值了。

引用变量被final修饰之后,虽然不能再指向其他对象,但是它指向的对象的内容是可变的。

static作用于成员变量用来表示只保存一份副本,而final的作用是用来保证变量不可变。

Last modification:July 30th, 2020 at 07:10 pm
如果觉得我的文章对你有用,请随意赞赏