天天看点

final关键字详解-Java

摘要

final关键字的作用是在不同的场合下限制扩展。本文旨在详细描述Java关键字final的使用。下文将主要介绍class,method以及variable的不同使用场景。

类(class)

当用final修饰class时,此类将不能被继承。Java核心库String类,就是一个final class。其它类不能继承String类。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence,
    Constable, ConstantDesc {
        // omit code
}
           

举一个简单的例子,如下

final class Fruit {
    private int weight;
}

class Apple extends Fruit {
    
}
           

将会出现错误,表明Fruit类不能被继承。

总结:当该类不需要被继承时,可以使用final,阻止其被继承。

方法(method)

当用final修饰方法时,该方法不能被重写(override)。核心库中Thread类里面boolean isAlive(),该方法允许继承,但是不允许被override。

一个简单的例子如下,当要重写 public void getRealWeight()时,将会出现错误。所以Apple可以直接调用Fruit的 public void getRealWeight(),而不能override。

class Fruit {
    private int weight;

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public final int getRealWeight() {
        return weight / 2;
    }
}

class Apple extends Fruit {
    @Override
    public int getWeight() {
        return super.getWeight();
    }

    @Override
    public void setWeight(int weight) {
        super.setWeight(weight);
    }

    @Override
    public void getRealWeight() {
        return super.getRealWeight();
    }
}
           

错误如下

总结:当设计父类时,不想子类重写某些方法时,但是允许子类使用。可以使用final关键字修饰该方法。

变量(variable)

基础变量(primitive)

final 修饰局部基础变量(byte/short/int/long/char/boolean/float/double)时,该变量的值不能修改,也就是常量。举例如下,当给localVar赋值时,将会出现下面的错误。

final int localVar = 2323;
localVar = 23;
           

总结:当期望基础变量不需要被修改时,使用final。

引用变量(reference)

当final修饰引用变量时,也就是除基础变量其他的变量,形如class等时,同样,该变量不能被赋予新的值,但是可以改变其属性值。举个例子。

class Fruit {
    private int weight;

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public final int getRealWeight() {
        return weight / 2;
    }
}

final Fruit fruit = new Fruit();
fruit = new Fruit();
           

错误显示

当改变其属性值时,如下

final Fruit fruit = new Fruit();
fruit.setWeight(233);
System.out.println(fruit.getRealWeight()); // 116
           

总结:final修饰引用变量时,该变量不能被赋予新值,但是能够改变其属性值。

属性(field)

final修饰类的属性时,表示该属性不能被修改,即为常量。需要在声明处初始化。

具体使用,当需要价格不变时,可以设置为final。

class Fruit {
    public final int PRICE = 23;
    private int weight;

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public final int getRealWeight() {
        return weight / 2;
    }
}
           

总结:当需要设置某个属性为常量时,可以设置为final。

参数(arguments)

final修饰参数时,表示该参数在函数体内不能被赋值。具体的包括基础变量和引用变量。同样final修饰引用变量时,其属性值可以改变。举例如下。

static void setWeight(final Fruit fruit) {
fruit.setWeight(23233);
}

static int getWeight(final Fruit fruit) {
return fruit.getWeight();
}

final Fruit fruit = new Fruit();
setWeight(fruit);
System.out.println(getWeight(fruit)); // 23233

class Fruit {
    public final int PRICE = 23;
    private int weight;

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public final int getRealWeight() {
        return weight / 2;
    }
}
           

总结:final修改参数时,该变量都不能被赋值新值。但是修改引用变量时,其属性值可以改变。

参考文献

[1] final关键字的使用

[2] final关键字详解