一、final修饰符概述

1. final可以修饰类、变量和方法

2. final修饰的类、变量和方法不可改变

二、final成员变量

1. 对于final修饰的成员变量而言,一旦有了初始值,就不能被重新赋值

2. 由于成员变量不一定需要显式初始化,故那些既没有在定义时指定初始值,也没有在初始化块、构造器中指定初始值的final成员变量的值将一直是系统默认分配的0、'\u0000'、false或null,这些final成员变量也就完全失去了存在的意义,因此Java规定:final修饰的成员变量必须由程序员显式地指定初始值

  • final类变量:必须在静态初始化块中指定初始值或声明该类变量时指定初始值,而且只能在两个地方的其中之一指定
  • final实例变量:必须在非静态初始化块、声明该实例变量或构造器中指定初始值,而且只能在三个地方的其中之一指定
  // 定义final成员变量时指定默认值final int a = 6;// 下面final成员变量将在构造器或初始化块中分配初始值final String str;final int c;final static double d;// 下面定义的ch实例变量是不合法的,因为没有显式指定初始值// final char ch;// 初始化块,可对没有指定默认值的实例变量指定初始值{str = "Hello";}// 静态初始化块,可对没有指定默认值的类变量指定初始值static{d = 3.14;}// 构造器,可对既没有指定默认值,又没有在初始化块中指定初始值的实例变量指定初始值public FinalVariableTest(){c = 5;}

三、final局部变量

1. 相比于成员变量,系统不会对局部变量进行初始化,局部变量必须由程序员显式初始化,因此使用final修饰局部变量时,既可以在定义时指定默认值,也可以不指定默认值

  • 如果在定义时指定了默认值,则后面代码中不能再对该变量赋值
  • 如果在定义时未指定默认值,则可以在后面代码中对该final变量赋初始值,但只能一次,不能重复赋值

四、final变量→宏变量

1. 当某个final变量满足以下两个条件时,它就不再是一个变量,而是相当于一个直接量(即宏变量)

  • 在该final变量定义时指定了初始值
  • 该初始值可以在编译时就被确定下来

2. 除了为final变量赋值时赋直接量的情况外,如果被赋的表达式只是基本的算术表达式或字符串连接运算,没有访问普通变量,也没有调用方法,Java编译器同样会将这种final变量当成“宏变量”处理

     // ex:下面定义了4个final“宏变量”final int a = 5; final int b = 3 + 2;final double d = 1.2 / 3;final String str = "我爱" + "China";// 下面的ss变量的值因为调用了方法,所以无法在编译时被确定下来,ss也就不会被当成“宏变量”处理final String ss = "我爱China" + String.valueOf(1314);

  

五、final方法

1. final修饰的方法不可被重写,但完全可以被重载

2. 由于子类无法重写父类的private方法(如果子类中定义一个与父类private方法有相同方法名、相同形参列表、相同返回值类型的方法,也不是方法重写,只是重新定义了一个新方法),因此即使使用final修饰一个private方法,依然可以在其子类中定义与该方法具有相同方法名、相同形参列表、相同返回值类型的方法

public class PrivateFinalMethodTest
{private final void test() {}
}class sub extends PrivateFinalMethodTest
{// 下面的方法定义不会出现问题public void test() {}
}

注:虽然子类和父类都包含了同名的void test()方法,但子类并不是重写父类的方法,因此即使父类的void test()方法使用了final修饰,子类中依然可以定义void test()方法。

六、final类

1. final修饰的类不可以有子类,所以若某个类不想被继承,则可以使用final修饰该类

public final class FinalClass
{
}// 下面的类定义将出现编译错误
class Sub extends FinalClass
{
}

七、不可变类

1. 不可变类是指创建该类的实例后,该实例的实例变量是不可改变的

2. Java提供的8个包装类和java.lang.String类都是不可变类

3. 如果要创建自定义的不可变类,可遵守如下规则:

  • 使用private和final修饰符来修饰该类的成员变量
  • 提供带参数构造器,用于根据传入参数来初始化类里的成员变量
  • 仅为该类的成员变量提供getter方法,不要为该类的成员变量提供setter方法
  • 如果有必要,重写Object类的hashCode()和equals()方法
/** 定义一个不可变类Address*/
public class Address
{// 不可变类的实例的实例变量不可改变private final String detail;private final String postCode;public Address(){detail = "";postCode = "";}public Address(String detail, String postCode){this.detail = detail;this.postCode = postCode;}public String getDetail(){return this.detail;}public String getPostCode(){return this.postCode;}// 重写equals()方法,判断两个对象是否相等public boolean equals(Object obj){// ...}public int hashCode(){return detail.hashCode() + postCode.hashCode() * 31;}
}

补:对于上面的Address类,当程序创建了Address实例后,将无法修改该Address实例的detail和postCode实例变量。

4. 不可变类的实例在整个生命周期中永远处于初始化状态,它的实例变量不可改变,因此对不可变类的实例的控制将更加简单

  • 不可变类的实例状态不可改变,可以很方便地被多个对象所共享

转载于:https://www.cnblogs.com/xzxl/p/10998741.html

12. final修饰符相关推荐

  1. JAVA: final 修饰符

    final 修饰符 final 变量: final 表示"最后的.最终的"含义,变量一旦赋值后,不能被重新赋值.被 final 修饰的实例变量必须显式指定初始值. final 修饰 ...

  2. 1.19 final修饰符详解

    final 在 Java 中的意思是最终,也可以称为完结器,表示对象是最终形态的,不可改变的意思.final 应用于类.方法和变量时意义是不同的,但本质是一样的,都表示不可改变, 使用 final 关 ...

  3. java中final是修饰符么_Java final修饰符详解

    final 在 Java 中的意思是最终,也可以称为完结器,表示对象是最终形态的,不可改变的意思.final 应用于类.方法和变量时意义是不同的,但本质是一样的,都表示不可改变. 使用 final 关 ...

  4. Java final修饰符详解

    final 在 Java 中的意思是最终,也可以称为完结器,表示对象是最终形态的,不可改变的意思.final 应用于类.方法和变量时意义是不同的,但本质是一样的,都表示不可改变. 使用 final 关 ...

  5. JAVA基础-栈与堆,static、final修饰符、内部类和Java内存分配

    JAVA基础-栈与堆,static.final修饰符.内部类和Java内存分配 发布时间: 2013/01/12 22:29 QQ空间 新浪微博 腾讯微博 人人网 豆瓣网 百度空间 百度搜藏 开心网 ...

  6. 【Java】【final修饰符】

    一.思维导图 二.修饰符 1.修饰成员变量 final修饰类变量(静态变量) 代码: /** * final修饰类变量的两种情况 */ public class ExampleVariable{// ...

  7. java final修饰符_java final修饰符详解,final修饰方法

    之前给大家讲过java final修饰符final修饰变量方面的知识,那么下面要继续给大家讲到的就是final修饰方法方面的知识,一起来了解一下吧. final修饰的方法不能被重写,假如因为一些原因, ...

  8. private static final 修饰符

    java修饰符分类修饰符字段修饰符方法修饰符根据功能同主要分下几种 1.权限访问修饰符 public,protected,default,private,四种级别修饰符都用来修饰类.方法和字段 包外 ...

  9. 【Java】6.4 final 修饰符

    目录 final 成员变量 final局部变量 final修饰基本类型变量和引用类型变量的区别 可执行"宏替换"的final变量 final方法 final类 不可变类 缓存实例的 ...

最新文章

  1. 阿里云服务器部署项目
  2. 为什么要使用Go语言?Go语言的优势在哪里?
  3. pose2pose 姿态迁移
  4. 对于java的命名规范(标识符)
  5. 在上位计算机控制时不能将s7-200,PLC控制统编程题库.doc
  6. 线性表及其逻辑和存储结构(二级)
  7. 没有他,就没有我们现在的WebRTC
  8. Python学习笔记__10.4章 进程VS线程
  9. c语言 判断一个图是否全连通_基于云平台的全链路大规模网络连通性检测系统详解...
  10. PHP 练习(新闻发布)
  11. mongodb 分组聚合_MongoDB 临时表横空出现 1 万+,这条语句执行前请准备好翻车的姿势...
  12. 怀疑安装MySQL之后,导致OrCAD Capture、Allegro就打不开
  13. Taro+Vue3 - 配置@路径别名
  14. k8s中使用基于nfs的storageclass
  15. react前端项目_如何使用React前端设置Ruby on Rails项目
  16. 我的四核Cortex-A53学习之路
  17. waiting for a volume to be created, either by external provisioner “docker.io/hostpath“ or manually
  18. GMAN:一种用于交通预测的图多注意网络
  19. 波形系列之正弦波发生器-含仿真代码及工程
  20. 【Agile框架(一)】首页布局

热门文章

  1. MSVCRTD.lib(crtexe.obj) : error LNK2019
  2. Java五道输出易错题解析(进来挑战下)
  3. JVM实用参数(四)内存调优
  4. 【前端开发系列】—— CSS3属性选择器总结
  5. ROS探索总结(一)(二)(三):ROS总体框架 ROS总体框架 ROS新手教程
  6. Python+Django+Eclipse 在Windows下快速开发自己的网站
  7. bat 批处理切换到当前脚本所在文件夹
  8. 记一例 ORA-00904:标识符无效
  9. Spring Cloud的全局封装实践
  10. Project Structure详解