java中的final的作用(基础复习一波)

版权声明:转载请注明出处 https://blog.csdn.net/chenmingxu438521/article/details/90114419

一、概述

1.final修饰类

表示这个类不能被继承,如String,final类中的所有成员方法都会被隐式地指定为final方法。

2.修饰方法

java编程思想:

第一个原因是把方法锁定,以防任何继承类修改它的含义

第二个原因是效率,在早期的java实现版本中,会将final方法转为内嵌调用,但是由于方法过于庞大,可能看不到内嵌调用带来的任何性能提升,在最近的java版本中,不需要使用final方法进行这些优化了。

注:类的private方法会隐式地被指为final。

3.修饰变量

对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象,重新赋值会编译报错,如下。

Java中final关键字,18K的程序员都可能没彻底搞清楚

二、具体讲解

1.类的final变量和普通变量有什么区别?(重点)

java是这样设计的:final一生只认一个值,你初始化好了,他就不能在重新赋值。

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

1.1.下面这个例子是局部变量的例子(final在编译器就确认了值)

public class DemoTest {
    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);
    }
}

1.2.结果

true
false

1.3.下面这个例子是局部变量的例子(final在编译器不能确定getHello())

public class DemoTest {
    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";
    }
}

1.4.结果

false

2.被final修饰的引用变量指向的对象内容可变吗?

内容可变,不变的是地址,记住是地址,这个面试经常考。

3.final和static

3.1.static保证只有独一份。

3.2.final保证值不变,记住引用变量内容是可以变的。

4.匿名内部类中使用的外部局部变量为什么只能是final变量

Java中final关键字,18K的程序员都可能没彻底搞清楚

5.关于final参数的问题

使用final修饰方法参数的目的是防止修改这个参数的值,同时也是一种声明和约定,强调这个参数是不可变的


原因在于java采用的是值传递这个话题很受争议】,对于引用变量,传递的是引用的值【准确讲是内存里的地址】,也就是说让实参形参同时指向了同一个对象,因此让形参重新指向另一个对象对实参并没有任何影响。

public class DemoTest {
    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        StringBuffer buffer = new StringBuffer("hello");//实参
        myClass.changeValue(buffer);
        System.out.println(buffer.toString());
    }
}
public class MyClass {
    //形参()
    void changeValue(StringBuffer buffer){
        buffer.append("world");
    }
}

这里的buffer.append操作的地址跟实参是同一个,所以结果是hello world.

如果方法changeValue里,buffer=new StringBuffer("诺言");这里只能改变形参的地址,但不能改变实参的地址,所以打印结果是外面的 hello【这地方很容易翻车

public class MyClass {
    //形参()
    void changeValue(StringBuffer buffer){
        buffer.append("world");
        buffer=new StringBuffer("诺言");//形参值被改变,但不影响实参
        System.out.println(buffer); //诺言
    }
}

最后输出的还是 hello world

实参和形参【科普】

1、形参变量只有在被调用时才分配内存单元,在调用结束时,就会释放出所分配的内存单元。所以,形参只能在函数内部才有效;【生存周期在方法内

2、实参是:常量、变量、表达式、函数等,实参是何种类型的量,当开始在进行函数调用时,都必须有确定的值;【实参复杂值给形参】

3、在一般传值调用的机制中只能把实参传送给形参,因此在函数调用过程中,形参值发生改变,而实参中的值不会变化。【很重要

三、结束

Always keep the faith!!!

猜你喜欢

转载自blog.csdn.net/chenmingxu438521/article/details/90114419
今日推荐