你的位置:首页 > 软件开发 > Java > Java学习笔记18

Java学习笔记18

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

Java学习笔记18

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


作者: 蝉蝉

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

//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).把成员变量和局部变量从变量的类型上来分,

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

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

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

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

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

 

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

Java学习笔记18

 

2.final可以修饰成员方法

(1).final修饰的成员方法不能被子类重写,但子类可以调用。见下面的代码:

Person类的方法: final void finalMethod() {  int i = 2;  System.out.println("finalMethod: i = " + i); }在TestMain中由Student类的对象引用调用:public class TestMain { public static void main(String[] args) {  Student stu = new Student();    stu.finalMethod();}

输出结果为:finalMethod: i = 2

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

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

Person类的方法: private final void priFinalMethod() {  System.out.println("Person:priFinalMethod"); }Student类的方法: final void priFinalMethod() {  System.out.println("Student:priFinalMethod"); }TestMain类:package human;public class TestMain { public static void main(String[] args) {  Person per = new Person();  Student stu = new Student();  Person per1 = stu;  //  per.priFinalMethod();  stu.priFinalMethod();//  per1.priFinalMethod();}Person类的main方法: public static void main(String[] args) {  Person per = new Person();  Student stu = new Student();  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的,但成员变量是可以改变的,见下面代码:

package human;public final class FinalClass { int i = 1;  void test() {  System.out.println("FinalClass:test"); }  public static void main( String[] args ) {  FinalClass ficl = new FinalClass();    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类:

package human;public class Person {//class Person{ String name; int age; String gender;  //笔记18:final修饰成员变量,及成员变量为类引用时的情况 final int height = 160;// final int height; final EduBackground edu = new EduBackground();  public Person() { } //笔记18:final修饰局部变量、修饰成员方法、修饰方法的参数 //修饰局部变量时,局部变量的值不能改变 void finalLocal() {//  final int i = 1;  final int i;  //  i = 3;  final EduBackground edu = new EduBackground();//  edu = new EduBackground();  i = 1;  System.out.println("finalLocal: i = " + i); }  //修饰方法的参数时,参数不能被修改 void finalArgs(final int i) {//  i = 3;  System.out.println("finalArgs: i = " + i); } void finalArgs(final EduBackground edu) {//  edu = new EduBackground();  System.out.println("finalArgs: edu"); }  //修饰成员方法时,成员方法不能被子类重写 final void finalMethod() {  int i = 2;  System.out.println("finalMethod: i = " + i); } private final void priFinalMethod() {  System.out.println("Person:priFinalMethod"); } public static void main(String[] args) {  Person per = new Person();  Student stu = new Student();  Person per1 = stu;    per.priFinalMethod();  stu.priFinalMethod();  per1.priFinalMethod(); }}

 

Student类:

package human;public class Student extends Person { String stuNumber; int score;  public Student() {   }  //笔记18:子类不能重写父类被final修饰的方法// final void finalMethod() {//  int i = 2;//  System.out.println("finalMethod: i = " + i);// } final void priFinalMethod() {  System.out.println("Student:priFinalMethod"); }}
EduBackground类:
package human;//public class EduBackground extends FinalClass {public class EduBackground { String primarySchool; String secondarySchool; String juniorHSchool; String seniorHSchool; String university;  public EduBackground() {   }}

 

原标题:Java学习笔记18

关键词:JAVA

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。