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

作者: 蝉蝉

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

http://www.cnblogs.com/chanchan/p/7936388.html

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说明它是属于整个类的,类加载时就分配内存了(参见笔记9),final说明其值不可变,即,位置固定内容也固定。

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

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

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

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

如:

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

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

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

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

2.final可以修饰成员方法

(1).final修饰的成员方法不能被子类重写,即,当父类的方法为final时,子类不能与父类有方法名、参数类型、参数个数及参数顺序都一样的方法;父类方法为private时除外,详见下面的(3);但子类可以调用父类的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() {
//  final height = 160;
} //笔记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---final关键字修饰变量、方法及类的更多相关文章

  1. 《JAVA学习笔记 (final关键字)》

    [14-9]面向对象-final关键字 /* 继承的弊端,打破封装性. 不让其他类继承该类,就不会有重写. 怎么能实现呢?通过Java中的一个关键子来实现,final(最终化). [final关键字] ...

  2. Java学习笔记之——final关键字

    最终的,最后的 可以修饰:变量.方法.类 (1) 修饰变量 不可改变,即常量,只能赋值一次,赋值之后不可改变 a. 修饰属性:private final int num; 要求属性要显式赋值 通常在属 ...

  3. java学习笔记18(基本类型包装类,system类)

    基本类型包装类 定义:程序界面用户输入的数据都是以字符串类型存储的,如果需要操作这些字符串进行运算,需要转成基本数据类型,这时就要用到基本类型包装类,例: public class Demo { pu ...

  4. java学习面向对象之final关键字

    之前我们讲过继承的相关知识了,继承就是子类继承父类的属性和方法并且还可以覆盖父类的方法.但是这样有一个缺陷是什么呢,就是当我们一个类当中涉及一些封装的核心的东西或者对整个系统非常关键的方法或者类的时候 ...

  5. 0025 Java学习笔记-面向对象-final修饰符、不可变类

    final关键字可以用于何处 修饰类:该类不可被继承 修饰变量:该变量一经初始化就不能被重新赋值,即使该值跟初始化的值相同或者指向同一个对象,也不可以 类变量: 实例变量: 形参: 注意可以修饰形参 ...

  6. 0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类

    static可以修饰哪些成员 成员变量---可以修饰 构造方法---不可以 方法---可以修饰 初始化块---可以修饰 内部类(包括接口.枚举)---可以修饰 总的来说:静态成员不能访问非静态成员 静 ...

  7. Java中final关键字修饰变量、方法、类的含义是什么

    Java中的关键字final修饰变量.方法.类分别表示什么含义? 先看一个简单的介绍 修饰对象 解释说明 备注 类 无子类,不可以被继承,更不可能被重写. final类中的方法默认是final的 方法 ...

  8. java学习笔记(六):变量类型

    java一共三种变量: 局部变量(本地变量):方法调用时创建,方法结束时销毁 实例变量(全局变量):类创建时创建,类销毁时销毁 类变量(静态变量):程序启动是创建,程序销毁时销毁 public cla ...

  9. 疯狂java学习笔记之面向对象(二) - 成员变量与局部变量

    Java变量按其作用域可分为:成员变量和局部变量.注意:在Java中是没有全局变量这个概念的 一.成员变量: 成员变量是在类中定义的变量,具体可分为类变量与实例变量--有无static修饰 实例变量的 ...

  10. 1.6(java学习笔记)static关键字

    static关键字 1.static修饰变量也称静态变量,静态变量存放在静态区被该类的所有对象共享. 例如,定义了一个类class User{static Sring city = "a城& ...

随机推荐

  1. 免费靠谱的 Let’s Encrypt 免费 https 证书申请全过程

    申请 Let’s Encrypt证书的原因: 现在阿里云等都有免费的 https 证书,为什么还要申请这个呢(估计也是因为阿里云这些有免费证书的原因,所以 Let’s Encrypt 知道的人其实并不 ...

  2. less新手入门(二) Mixin 混合、带参数的Mixin

    四.mixin  混合 "mix - in"属性来自现有的样式!! 你可以在类选择器和id选择器中使用mixin, .a,#b{ color: rebeccapurple; } . ...

  3. 【c语言】实现一个函数,求字符串的长度,不同意创建第三方变量

    // 实现一个函数,求字符串的长度.不同意创建第三方变量. #include <stdio.h> #include <assert.h> int my_strlen_no(ch ...

  4. Android中相机和相冊使用分析

    Android中相机和相冊使用分析 欢迎转载,但请尊重原创(文章来自不易,转载请标明转载出处,谢谢) 在手机应用程序中,使用自带的相机拍照以及相冊选择喜欢的图片是最常见只是的用户需求,那么怎么合理使用 ...

  5. x86 处理器开机顺序

    无论是千万行的linux ,还是百万行的uefi ,或者百十行的app, 它都有一个主线.应用程序是main() 函数里面全部函数运行完,程序结束.这里main() 做为程序的起点,uefi 能够觉得 ...

  6. 微服务架构之RPC-client序列化细节

    通过上篇文章的介绍,知道了要实施微服务,首先要搞定RPC框架,RPC框架的职责要向[调用方]和[服务提供方]屏蔽各种复杂性: (1)让调用方感觉就像调用本地函数一样 (2)让服务提供方感觉就像实现一个 ...

  7. Python笔记·第七章—— IO(文件)处理

    一.文件处理简介 计算机系统分为:计算机硬件,操作系统,应用程序三部分. 我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众所周知 ...

  8. Elasticsearch聚合——aggregation

    聚合提供了分组并统计数据的能力.理解聚合的最简单的方式是将其粗略地等同为SQL的GROUP BY和SQL聚合函数.在Elasticsearch中,你可以在一个响应中同时返回命中的数据和聚合结果.你可以 ...

  9. Tomcat配置(二):tomcat配置文件server.xml详解和部署简介

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  10. [转]addEventListener() 方法,事件监听

    转载  白杨-M  http://www.cnblogs.com/baiyangyuanzi/p/6627401.html addEventListener() 方法,事件监听 你可以使用 remov ...