原文链接https://www.cnblogs.com/dolphin0520/p/10651845.html

作者Matrix海 子

本文为笔记

0. 概述

final和static一样都是修饰词,final用来修饰类、方法、变量(包括局部变量和成员变量)。

1. final修饰类

被final修饰的类表示不可被继承,并且此时该类中的所有成员方法都会被隐式地修饰为final。

一般不把类定义为final类。

2. final修饰方法

说明这种方法提供的功能已经满足当前要求,不需要进行扩展,并且也不允许任何从此类继承的类来重写这种方法。

但是继承仍然可以继承这个方法,也就是说可以直接使用被final修饰的方法。在声明类中,一个 final 方法只被实现一次。

也就是只有明确不想被覆盖的方法会被修饰为final。

类的private方法会隐式地被指定为final方法

3. final修饰变量

  • 如果被修饰的变量是基本数据类型,则这个变量的值不会被改变。
  • 如果被修饰的变量是引用类型,则这个变量初始化后无法指向其他对象,但是指向的对象的值可以发生改变

3.1 final修饰成员变量

final修饰成员变量时,必须要保证该成员变量在被声明时或者构造器中就被赋值了,且一旦初始化完成,值就不能被改变了。

有如下代码

public class Test {
public static void main(String[] args) {
String a = "hello2";
final String b = "hello";
String d = "hello";
String c = b + 2;
String e = d + 2;
System.out.println((a == c));
System.out.println((a == e));
}
}
/*
true
false
*/

此处的结果蕴含着final的特点:当final修饰基本数据类型和String时,如果在编译器就能知道这个变量的值,则编译器会把它当做编译期常量使用,类似C中的宏。于是此时的a和c实际指向了同一个引用,而e指向的是一块新的引用。

但是这个特性实现的前提是在编译期间就能知道具体的值,而如下所示

public class Test {
public static void main(String[] args) {
String a = "hello2";
final String b = getHello();
String c = b + 2;
System.out.println((a == c));
} public static String getHello() {
return "hello";
}
}
// false

上述代码在程序实际运行时,b才能通过调用getHello函数从而被初始化,所以无法在编译期间就获取到值,因此结果为false。

3.2 final修饰局部变量

注意Java中采用的是值传递,所以在调用时要注意。例如

public class Test {
public static void main(String[] args) {
MyClass myClass = new MyClass();
int i = 0;
myClass.changeValue(i);
}
} class MyClass {
void changeValue(int i) {
i++;
}
}
//Error

上述代码会报错,因为在changeValue函数体中,i被识别为局部变量。而该变量为final,无法改变i的值。

4. final和static

修饰成员变量时,final保证不可变,static表示每个对象都有一份副本。

public class Test {
public static void main(String[] args) {
MyClass myClass1 = new MyClass();
MyClass myClass2 = new MyClass();
System.out.println(myClass1.i);
System.out.println(myClass1.j);
System.out.println(myClass2.i);
System.out.println(myClass2.j);
}
} class MyClass {
public final double i = Math.random();
public static double j = Math.random();
}
// myClass1.i != myClass2.i
// myClass1.j == myClass2.j

i被修饰为final,表示不可变,而j表示所有对象共享同一个j,所以i不同,j相同。

Java中final的使用的更多相关文章

  1. Java中final的作用

    Java中Final可以被用于变量,方法,类.具体来说: 1, Final 变量 修饰主类型时,制定变量为常数,不希望被改变 修饰类类型时,表示变量的句柄不变,不能被指定指向新的变量 修饰参数时,参数 ...

  2. 深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因

    声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/det ...

  3. java中final的意义

    1.如果一个数据既是static又是final,那么它会拥有一块无法改变的存储空间. 2.final data: 当final用于基本数据类型时,final让其值(value)保持不变,但是当用于ob ...

  4. Java中final修饰符深入研究

    一.开篇 本博客来自:http://www.cnblogs.com/yuananyun/ final修饰符是Java中比较简单常用的修饰符,同时也是一个被"误解"较多的修饰符.对很 ...

  5. 【Java面试题系列】:Java中final finally finalize的区别

    本篇为[Java面试题系列]第三篇,文中如有错误,欢迎指正. 第一篇链接:[Java面试题系列]:Java基础知识常见面试题汇总 第一篇 第二篇链接:[Java面试题系列]:Java基础知识常见面试题 ...

  6. Java中final,finally和finalize区别

    Day11_SHJavaTraing_4-18-2017 Java中final,finally和finalize区别 1.final—修饰符(关键字) ①final修饰类,表示该类不可被继承 ②fin ...

  7. Java中final修饰的数据

    目录 Java中final修饰的数据 有初始值的final域 final+基本数据类型 final+引用数据类型 final与static final 空白final域 final修饰的参数 基本数据 ...

  8. 转 Java中final、finally、finalize的区别与用法

    Java中final.finally.finalize的区别与用法   1.简单区别:final用于声明属性,方法和类,分别表示属性不可交变,方法不可覆盖,类不可继承.finally是异常处理语句结构 ...

  9. java中final 、finally、finalize的区别

    比较java中常用关键字以免混淆 final :用来修饰变量,表示变量为最终变量,不能被改变 finally:在处理异常的时候使用,表示最终要执行的代码块 finalize:java Object类中 ...

  10. Java中 final static super this instanceof 关键字用法

    一.final关键字 final可以修饰变量.方法及类: 1.当定义一个final变量时,jvm会将其分配到常量池中,其所修饰的对象只能赋值一次,对基本类型来说是其值不可变,引用类型(包括作为函数形参 ...

随机推荐

  1. hadoop 无法访问50070

    windows无法访问hadoop web端口 windows hosts文件:C:\Windows\System32\drivers\etc centos防火墙没有关,关闭参考 hadoop cor ...

  2. 服务器CPU很高-怎么办(Windbg使用坑点)

    最近,碰到了一个线上CPU服务器很高的问题,并且也相当紧急,接到这个任务后,我便想到C#性能分析利器,Windbg. 终于在折腾半天之后,找出了问题,成功解决,这里就和大家分享一下碰到的问题. 问题1 ...

  3. 【Oracle】PLSQL如何更新、提交数据库中数据

    转至:https://blog.csdn.net/Bee_AI/article/details/89279612 Oracle更新单表数据时,一般使用SELECT--FOR UPDATE语句,这条语句 ...

  4. LVM--逻辑卷管理@安装、格式化、挂载、开机自动挂载完整篇

    转至:https://blog.51cto.com/xiguatailang/1256606      LVM的重要性在这里我也就不多说了,今天和大家分享一下,LVM的安装方式,以及挂载方式. 首先呢 ...

  5. 给页面添加Canvas鼠标光标星星跟随动画特效

    素材来源:https://www.lanrenzhijia.com/others/5024.html 简单说下我自己的步骤: 把<script type="text/javascrip ...

  6. curl 命令常用

    参考: https://www.cnblogs.com/name-lizonglin/p/12167808.html -- 测试 请求返回时间  测试Pod 之间解析时间   用key为空字符串查me ...

  7. 新建vue3.0 项目—步骤详细介绍

    一.环境搭建 1.安装node环境(版本≥ 8.9) 2.安装vue-cli3.0 npm install @vue/cli -g 此处省略安装步骤截图了,相信各位都已装好了,下图为查看版本结果: 二 ...

  8. AE初步

    AE开发就是我们常说的ArcEngine二次开发. 1.配置环境 目前来讲,稳定的版本配置,一般配置为VS2012+ArcEngine10.2. 安装ArcEngine时,安装图中三项即可,顺序为Ar ...

  9. Windows 10平台安装PostgreSQL 14.2详细教程

    Windows 10平台安装postgreSQL 14.2.1,安装步骤很简单,基本上是点击下一步(next). 使用SQL Shell(psql)进行交互:使用pgAdmin工具进行管理. tips ...

  10. CentOS7.5环境下安装配置GitLab

    1. 安装依赖软件 yum -y install policycoreutils openssh-server openssh-clients postfix 2.设置postfix开机自启,并启动, ...