java 中final修饰的变量_Java学习笔记18---final关键字修饰变量、方法及类

本文详细介绍了Java中的final关键字,包括它可以修饰变量、成员方法和类,以及修饰方法参数的用法。final修饰的变量不可更改,成员方法不能被重写,修饰类则禁止子类继承。此外,还讨论了final修饰引用类型变量时的特殊性。
摘要由CSDN通过智能技术生成

英语里final这个单词大家都知道是“最终的”意思,其实还有一个意思是“不可更改的”。在Java里,final关键字作“不可更改的”来解释更合适,即由final修饰的东西是“不可更改的”。final可以修饰变量、成员方法和类,还可以修饰方法的参数,但参数归根结底还是变量。下面是详细解释。

作者: 蝉蝉

请尊重作者劳动成果,转载请在标题注明“转载”字样,并标明原文链接:

1.final可以修饰成员变量、局部变量

(1).final修饰的变量的值不能更改,即不能再次赋值,即使赋的新值与旧值一样也不可以。

如:

final int i = 1; //定义int型变量i,并赋初值为1

//i = 2; //wrong

//i = 1; //wrong

注释掉的这两行都不可以,都会出现“The final local variable i can not be assigned.It must be blank and not using a compound assignment.”的错误。

(2).final修饰的成员变量和局部变量需要在使用前赋值。

1).对成员变量而言,可以在定义时直接赋初值;

2).也可以先定义不赋初值,再在构造方法中对其赋值。

就是说,对象创建好后,该对象的final成员变量要保证是赋了初值的,早点(定义时赋值)、晚点(在构造方法里赋值)都没关系。

注:第二种情况,如果有多个构造方法就比较麻烦了,每个构造方法都要有赋值语句,否则会出现“The blank final field height may not have been initialized.”的错误。

3).如果静态成员变量被修饰为final,那么该变量可看成是全局变量,即在类的整个加载期间,其值都不可变。

如:

static final String citizenship = "Chinese";

citizenship既是static又是final的,static说明它是属于整个类的,类加载时就分配内存了(参见

(3).把成员变量和局部变量从变量的类型上来分,

1).当变量为基本数据类型时,变量的值不可更改,如上面的变量i;

2).当变量为引用类型时,变量本身的值不可更改,即该变量不能指向其他的对象或数组;

但该变量指向的对象或数组本身的内容是可以改变的;

如:

final Person per = new Person(); //定义了一个Person类的对象引用per,并指向了new的对象

//per = new Person(); //重新创建一个Person类对象,并让per指向它,会出现与上面一样的错误,即final修饰的引用类型变量不能重新赋值

per.name = "me"; //per指向的对象本身的内容可以更改

为方便理解起见,请参考下面的内存图:

29caf0b2b2aed03d9a2f5bc558aa3bc5.png

2.final可以修饰成员方法

(1).final修饰的成员方法不能被子类重写,即,当父类的方法为final时,子类不能与父类有方法名、参数类型、参数个数及参数顺序都一样的方法;父类方法为private时除外,详见下面的(3);但子类可以调用父类的final方法。

见下面的代码:

Person类的方法:final voidfinalMethod() {int i = 2;

System.out.println("finalMethod: i = " +i);

}

在TestMain中由Student类的对象引用调用:public classTestMain {public static voidmain(String[] args) {

Student stu= newStudent();

stu.finalMethod();

}

输出结果为:finalMethod: i = 2

(2).访问权限为private的方法默认为final的,但子类不可以调用private的方法,关于访问权限修饰符的问题,详见

(3).当父类某方法为private final,子类的成员方法与父类的该成员方法重名但仅由final修饰时,这时算不算重写呢?

Person类的方法:private final voidpriFinalMethod() {

System.out.println("Person:priFinalMethod");

}

Student类的方法:final voidpriFinalMethod() {

System.out.println("Student:priFinalMethod");

}

TestMain类:packagehuman;public classTestMain {public static voidmain(String[] args) {

Person per= newPerson();

Student stu= newStudent();

Person per1=stu;//per.priFinalMethod();

stu.priFinalMethod();//per1.priFinalMethod();

}

Person类的main方法:public static voidmain(String[] args) {

Person per= newPerson();

Student stu= newStudent();

Person per1=stu;

per.priFinalMethod();

stu.priFinalMethod();

per1.priFinalMethod();

}

TestMain类的输出是:

Student:priFinalMethod

1).其中,TestMain类中注释掉的两行都提示该方法不可见;

2).对于per来说,private的方法仅本类可见,在TestMain类中是不可见的,所以per是不能调用priFinalMethod方法的;

3).对于per1来说,per1是指向Student对象的引用,per1只能调用Student中重写过的方法及Person类中的方法,由于这里仍然提示该方法不可见,结合2)可知,priFinalMethod方法是没被子类重写的,否则就可以调用了;

Person类的输出是:

Person:priFinalMethod

Student:priFinalMethod

Person:priFinalMethod

前两行好理解,最后一行,per1调用的是Person类中的priFinalMethod,进一步说明该方法未被子类重写;

否则,会优先调用子类的priFinalMethod方法的。

3.final可以修饰成员方法的参数

由final修饰的成员方法的参数也是不能更改的,其实参数就是变量,具体参见1即可。

这里还涉及到形参与实参的概念,具体大家自己了解吧。

4.final可以修饰类

由final修饰的类不能被子类继承,其成员方法也默认为final的,但成员变量是可以改变的,见下面代码:

packagehuman;public final classFinalClass {int i = 1;voidtest() {

System.out.println("FinalClass:test");

}public static voidmain( String[] args ) {

FinalClass ficl= newFinalClass();

System.out.println("ficl.i = " +ficl.i);

ficl.i= 2;

System.out.println("ficl.i = " +ficl.i);

}

}

输出结果为:

ficl.i = 1

ficl.i = 2

可见可以修改i的值。

附测试源码:

Person类:

packagehuman;public classPerson {//class Person{

String name;intage;

String gender;//笔记18:final修饰成员变量,及成员变量为类引用时的情况

final int height = 160;//final int height;

final EduBackground edu = newEduBackground();publicPerson() {

//  final height = 160;

}//笔记18:final修饰局部变量、修饰成员方法、修饰方法的参数//修饰局部变量时,局部变量的值不能改变

voidfinalLocal() {//final int i = 1;

final inti;//i = 3;

final EduBackground edu = newEduBackground();//edu = new EduBackground();

i = 1;

System.out.println("finalLocal: i = " +i);

}//修饰方法的参数时,参数不能被修改

void finalArgs(final inti) {//i = 3;

System.out.println("finalArgs: i = " +i);

}void finalArgs(finalEduBackground edu) {//edu = new EduBackground();

System.out.println("finalArgs: edu");

}//修饰成员方法时,成员方法不能被子类重写

final voidfinalMethod() {int i = 2;

System.out.println("finalMethod: i = " +i);

}private final voidpriFinalMethod() {

System.out.println("Person:priFinalMethod");

}public static voidmain(String[] args) {

Person per= newPerson();

Student stu= newStudent();

Person per1=stu;

per.priFinalMethod();

stu.priFinalMethod();

per1.priFinalMethod();

}

}

Student类:

packagehuman;public class Student extendsPerson {

String stuNumber;intscore;publicStudent() {

}//笔记18:子类不能重写父类被final修饰的方法//final void finalMethod() {//int i = 2;//System.out.println("finalMethod: i = " + i);//}

final voidpriFinalMethod() {

System.out.println("Student:priFinalMethod");

}

}

EduBackground类:

packagehuman;//public class EduBackground extends FinalClass {

public classEduBackground {

String primarySchool;

String secondarySchool;

String juniorHSchool;

String seniorHSchool;

String university;publicEduBackground() {

}

}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值