Java面向对象(高级)-- final关键字的使用

文章目录

  • 一、 final的意义
  • 二、 final的使用
    • (1) final修饰类
    • (2) final修饰方法
    • (3) final修饰变量
      • 1. 修饰成员变量
        • 1.1 举例1
        • 1.2 举例2
      • 2. 修饰局部变量
        • 2.1 举例1
        • 2.2 举例2
    • (4)final搭配static
    • (5)总结
  • 三、 笔试题
    • (1)题1
    • (2)题2

一、 final的意义

final:最终的,不可更改的

final可以用来修饰的结构:类、方法、变量(成员变量、局部变量)

二、 final的使用

(1) final修饰类

表示这个类不能被继承,没有子类。提高安全性,提高程序的可读性。

例如:String类、System类、StringBuffer类

final class Eunuch{//太监类
	
}
class Son extends Eunuch{//错误
	
}

【举例】

正常情况下:

class A{

}

class B extends A{

}

若此时类A前面有final修饰,则B无法继承于A。如下:

Java面向对象(高级)-- final关键字的使用_第1张图片

什么样的需要用final去修饰呢?

功能不需要再被扩展了,比如String类、StringBuffer类、StringBuilder类。

Java面向对象(高级)-- final关键字的使用_第2张图片

会发现String加了一个final修饰:

public final class String...

这就意味着不能去声明一个类去继承于String。

Java面向对象(高级)-- final关键字的使用_第3张图片

Stirng类用final修饰,没有必要再进行功能的扩展。

(2) final修饰方法

表示这个方法不能被子类重写

例如:Object类中的getClass()

class Father{
	public final void method(){
		System.out.println("father");
	}
}
class Son extends Father{
	public void method(){//错误
		System.out.println("son");
	}
}

【举例】

正常情况下:

class C{
    public void method(){

    }
}

class D extends C{
    //此时可以
    public void method(){

    }
}

若是method()方法前面有final修饰,就不能重写了。如下:

Java面向对象(高级)-- final关键字的使用_第4张图片

什么样的方法需要用final去修饰呢?

这个方法已经设计的很完备了,也没有扩展的必要性,就可以用final修饰。

比如Object类中的getClass()

可以看一下,首先Ctrl+N调出搜索框,输入“Object”:

Java面向对象(高级)-- final关键字的使用_第5张图片

然后Ctrl+F12,搜索”getClass“:

Java面向对象(高级)-- final关键字的使用_第6张图片

然后可以看到getClass被final修饰,表示这个方法不能被重写了。这个方法的作用就是获取当前对象所属的类,不需要重写。

Java面向对象(高级)-- final关键字的使用_第7张图片

native表示调用的是本地的方法,会调用底层C、C++相关的代码。

native修饰的getClass()方法若是调用的时候,这个方法的栈帧会进入栈中,此时它入的栈叫做本地方法栈

这个本地方法,就是指native修饰的方法。

为啥getClass()方法没有方法体?因为它调用的是底层的C、C++,不是用java代码写的,所以没有方法体。它会链接到相关dll文件中的C、C++代码。

在早期,Java发展不成熟的时候,会用到native。

(3) final修饰变量

final修饰某个变量(成员变量或局部变量),一旦赋值,它的值就不能被修改,即常量,常量名建议使用大写字母。

例如:final double MY_PI = 3.14;

如果某个成员变量用final修饰后,没有set方法,并且必须初始化(可以显式赋值、或在初始化块赋值、实例变量还可以在构造器中赋值)

1. 修饰成员变量

1.1 举例1
public class FinalTest {
    public static void main(String[] args) {
        E e=new E();
        System.out.println(e.MIN_SCORE);    //可以调用
    }
}

class E{
    //成员变量
    final int MIN_SCORE=0;
}

常量MIN_SCORE可以被调用,但是不能更改:

Java面向对象(高级)-- final关键字的使用_第8张图片

若此时将常量的显示赋值删掉,发现不可以:

Java面向对象(高级)-- final关键字的使用_第9张图片

没有默认值吗?

对于final修饰的成员变量,这时候默认值就不好使了。即使想用默认值0,也需要写出来。


若用方法赋值,不可以:

Java面向对象(高级)-- final关键字的使用_第10张图片

方法需要用对象去调用,而调用对象的时候,这个值该有就应该得有了。

之前说过给类的实例变量赋值的位置,其中默认初始化、显示初始化、代码块中初始化、构造器中初始化,它们在造对象过程中实现;而通过“对象.属性”或“对象.方法”进行赋值的时候,对象已经有了。

现在我们给常量赋值,意思就是当创建完对象的时候,这些属性的值就应该要有了。

后续调用方法(比如setRight()方法),体现为修改这个值。

而在声明它的时候没有赋值,而在有了对象之后,方法里面又不能修改这个值。

Java面向对象(高级)-- final关键字的使用_第11张图片

当对象创建完,属性的值就应该确定下来了。

有哪些位置可以给成员变量赋值?

  • 显式赋值
  • 代码块中赋值
  • 构造器中赋值
class E{
    //成员变量
    //1.默认赋值--NO
    //final int MIN_SCORE;

    //2.显示赋值--YES
    final int MIN_SCORE=0;

    //3.代码块中赋值--YES
    final int MAX_SCORE;
    {
        MAX_SCORE=100;  //一旦赋值就不可以再次赋值
    }

    //4.构造器中赋值--YES
    final int LEFT;
    public E(){ //用此构造器造完对象LEFT就赋完值了
        LEFT=2;
    }

    public E(int left){ //不同构造器都需要对常量LEFT赋值,每造一个对象就会拥有一份LEFT,所以每个对象的LEFT可以不同,但是一旦赋值不可更改
        LEFT=left;
    }

    //5.方法赋值--NO
    /*final int RIGHT;    //没有在允许的位置赋值
    public void setRIGHT(int right){
        RIGHT=right;    //有了对象之后,不能在方法里面修改常量的值
    }*/
    
}
1.2 举例2
public final class Test {
    public static int totalNumber = 5;
    public final int ID;

    public Test() {
        ID = ++totalNumber; // 可在构造器中给final修饰的“变量”赋值
    }
    public static void main(String[] args) {
        Test t = new Test();
        System.out.println(t.ID);
    }
}

2. 修饰局部变量

final修饰局部变量:一旦赋值就不能修改

2.1 举例1
  • 方法内声明的局部变量:在调用局部变量前,一定需要赋值。而且一旦赋值,就不可更改。

【举例】

一般情况下:

class F{
    public void method(){
        int num=10;
        num++;
        System.out.println(num);
    }
}

若此时给num加上final,就不可以对num更改了:

Java面向对象(高级)-- final关键字的使用_第12张图片

如下:

class F{
    public void method(){
        final int num=10;   //写两行也没事,只要在调用它之前赋上值就行,一旦赋值不可更改
        //num++;
        System.out.println(num);
    }
}

  • 方法的形参:在调用此方法时,给形参进行赋值。而且一旦赋值,就不可更改。

【举例】

一般情况下:

class F{
    public void method(int num){
        num++;
        System.out.println(num);
    }
}

若是给num加上final,num就是一个常量,这个常量还是在调用的时候赋的,那么赋完值之后就不要更改了。

Java面向对象(高级)-- final关键字的使用_第13张图片

如下:

class F{
    public void method(final int num){
        //num++;    //赋完值之后就不要更改了
        System.out.println(num);
    }
}
2.2 举例2
public class TestFinal {
    public static void main(String[] args){
        final int MIN_SCORE ;
        MIN_SCORE = 0;
        final int MAX_SCORE = 100;
        MAX_SCORE = 200; //非法
    }
}
  • 错误演示:
class A {
    private final String INFO = "atyuyi";  //声明常量

    public void print() {
        //The final field A.INFO cannot be  assigned
        //INFO = "雨翼轻尘"; 
    }
}

(4)final搭配static

finalstatic搭配:修饰成员变量时(不能是局部变量,static不能修饰局部变量),此成员变量称为:全局常量。(只有一个且不能改变

这个变量兼具final和static的特点。

比如:Math的PI (直接通过类来调用且不能变)

在实际写代码的时候,若是在修饰类、修饰方法的时候忘记使用不碍事,但是修饰变量的时候记得加上,而且变量名要大写。

(5)总结

1、 final的理解:最终的

2、final可以用来修饰的结构:类、方法、变量(成员变量、局部变量)

3、具体说明:

  • final修饰:表示此类不能被继承。
    比如:String、StringBuffer、StringBuilder类

  • final修饰方法:表示此方法不能被重写
    比如:Object类中的getClass()

  • final修饰变量:既可以修饰成员变量,也可以修饰局部变量。
    此时的"变量"其实就变成了"常量",意味着一旦赋值,就不可更改。

    • final修饰成员变量: 有哪些位置可以给成员变量赋值?
      > 显式赋值
      > 代码块中赋值
      > 构造器中赋值

    • final修饰局部变量:一旦赋值就不能修改
      > 方法内声明的局部变量:在调用局部变量前,一定需要赋值。而且一旦赋值,就不可更改
      > 方法的形参:在调用此方法时,给形参进行赋值。而且一旦赋值,就不可更改

4、 finalstatic搭配:修饰成员变量时,此成员变量称为:全局常量。
比如:Math的PI

三、 笔试题

(1)题1

排错

public class Something {
    public int addOne(final int x) {
        //return ++x;	//不可以
        return x + 1;	//可以,x值没有变
    }
}

(2)题2

排错

public class Something {
    public static void main(String[] args) {
        Other o = new Other();
        new Something().addOne(o);
    }
    public void addOne(final Other o) {
        // o = new Other();
        o.i++;	//让i++可以,因为i是变量,o不能变
    }
}
class Other {
    public int i;
}

局部变量o指向一个Other对象,Other对象里面有一个i,i没有用final修饰,表示它是一个变量。

将o加了一个final,意味着它的地址不能变了,而o指向的对象的属性可以变化。

如下:
Java面向对象(高级)-- final关键字的使用_第14张图片

你可能感兴趣的:(Java基础,java,面向对象(高级),final关键字)