一、使用到final的场景:
1、当不希望类被继承时,可以用final修饰
final class A{}
2、当不希望父类的某个方法被子类覆盖/重写时,可以用final修饰
class A{
public final void hi(){}
}
3、当不希望类的某个属性的值被修改,可以用final修饰
class A{
public final double TAX_RATE=0.08;
}
4、当不希望某个局部变量被修改,可以用final修饰
class A{
public void cry(){
final double NUM=0.01;
}
}
二、细节:
1、final修饰的属性又叫常量,一般用XX_XX_XX来命名(大写)
2、final修饰的属性在定义时,必须赋初值,且以后不能再修改,赋值可以在如下位置之一赋初值:
(1)定义时
(2)在构造器中
(3)在代码块中
class AA {
public final double TAX_RATE = 0.08;//1、定义时
public final double TAX_RATE2;//2、在构造器中
public final double TAX_RATE3;//3、在代码块中
public AA() {
TAX_RATE2 = 1.1;
}
{
TAX_RATE3=8.8;
}
}
3、如果final修饰的属性是静态的,则初始化的位置只能是:
(1)定义时
(2)在静态代码块
(3)不能在构造器中赋值(因为静态早于构造器)
4、final类不能继承,但可以实例化对象
final class AA{}
5、如果类不是final类,但含有final方法,则该方法虽然不能重写,但可以被继承
package final_;
public class FinalDetail01 {
public static void main(String[] args) {
new BB().cal();
}
}
class AA{
public final void cal(){
System.out.println("cal()方法");
}
}
class BB extends AA{}
//输出:cal()方法
4、5点小结:
final修饰的类,不能被继承,可以实例化
final修饰的函数不能被重写,可以被继承
6、一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法
(不能被继承,所以没有子类,所以不可能被重写,也就不需要用final修饰)
7、final不能修饰构造方法(即构造器)
8、final和static往往搭配使用,效率更高,不会导致类加载,底层编译器做了优化处理
(1)final+static,可以调用类的局部变量,而不会加载类
(2)public, static, final三个顺序没有要求,按习惯来
package final_;
public class FinalDetail01 {
public static void main(String[] args) {
System.out.println(BB.num);
}
}
class BB{
public final static int num=1000;//加了static后,只输出:1000,不会加载类,不会输出那句话
static {
System.out.println("BBB静态代码块被执行……");
}
}
9、包装类(Integer,Double,Float,Boolean等都是final),String也是final类
三、练习
1、
//我的答案:
//编写一个程序,能够计算圆形的面积,要求圆周率为3.14,赋值的三个方式都写
package final_;
import java.awt.geom.Area;
public class FinalExercise01 {
public static void main(String[] args) {
Area01 t1=new Area01(3.0);
System.out.println(t1.area());
}
}
class Area01{
private final double PI1=3.14;
private final double PI2;
private final static double PI3;
private double radius;
static {
PI3=3.14;
}
public Area01(double radius) {
this.radius = radius;
PI2=3.14;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double area(){
return PI1*radius*radius;
}
}
//老师的答案:
package final_;
public class FinalExercise01 {
public static void main(String[] args) {
Circle circle=new Circle(5.0);
System.out.println("面积="+circle.calArea());
}
}
class Circle{
private double radius;
private final double PI=3.14;
public Circle(double radius) {
this.radius = radius;
//PI=3.14;
}
{
//PI=3.14;
}
public double calArea(){
return PI*radius*radius;
}
}
//输出:面积=78.5
2、
public class Something{
public int addOne(final int x){
++x;//错误,原因是不能修改final x的值
return x+1;//正确
}
}
//形参不能是常量?
//这里不是这样的,这里传进来的参数相当于是在方法体里的局部变量,所以自然可以用final修饰