深入解析final关键字的用法
夫陶公
清风
千古,余又何人,敢称庶几
个人博客地址:http://blog.breez.work
文章目录
- 介绍
- 解析
- final属性
- final方法
- final参数
- final类
介绍
final用于声明属性【属性不可变】、方法【方法不可覆盖】、类(除了抽象类)【类不可被继承】
解析
final属性
被final修饰的
变量不可变
。【引用不可变
】
public class FinalTest {public static void main(String[] args) {final StringBuffer s = new StringBuffer("Hello");s.append(" World");System.out.println(s); //输出Hello World}
}
public class FinalTest {public static void main(String[] args) {final StringBuffer s = new StringBuffer("Hello World");s = new StringBuffer("Hello world"); //编译报错}
}
从上面可以看出final指的是引用不可变
,即它只能指向初始化时指向的那个对象
,不关心指向对象内容
的变化。所以被final修饰的变量
必须被初始化。
如何初始化:
- 在定义的时候初始化
final String name="BreezAm";
name="change"; //编译错误
- final成员变量可以在
初始块中
初始化,但不可在静态块中初始化。
- 在初始化块中初始化:【
编译通过
】
public class FinalTest {private final String name;//定义一个成员变量{name = "BreezAm";//初始化块中初始化成员变量name}public static void main(String[] args) {FinalTest test = new FinalTest();String name = test.name;System.out.println(name);//BreezAmtest.name="change";//编译报错}
}
试图在静态初始化块
中初始化final变量【编译报错
】
public class FinalTest {private final String name;// 编译报错static{name = "BreezAm"; //编译报错,就算name定义时已经被初始化此处编译期也会报错}public static void main(String[] args) {FinalTest test = new FinalTest();String name = test.name;System.out.println(name);//BreezAm}
}
静态
final成员变量可以在静态初始化块
中初始化,但不可以在初始化块
中初始化。
- 在
静态初始化块
中初始化成员变量【编译通过
】
public class FinalTest {private static final String name;// 定义一个静态、不可变的变量static {name = "BreezAm";//在静态初始化块中初始化}public static void main(String[] args) {String name = FinalTest.name;System.out.println(name);//BreezAm}
}
- 试图在
静态初始化块
中初始化成员变量【编译报错
】
public class FinalTest {private static final String name;// 编译报错{name = "BreezAm";//在初始化块中初始化}public static void main(String[] args) {String name = FinalTest.name;System.out.println(name);//BreezAm}
}
- 在类的
构造器
中初始化,但静态final成员变量
不可以在构造函数中初始化。
- 在
构造器
中初始化非静态
final成员变量【编译通过
】
public class FinalTest {private final String name;// 定义一个成员变量【未初始化】public FinalTest() {name = "BreezAm";//在构造器中初始化final类型的成员变量}public static void main(String[] args) {FinalTest test = new FinalTest();String name = test.name;System.out.println(name);//BreezAm}
}
final方法
当一个方法被声明为final时,该方法
不允许任何子类重写
这个方法,但子类仍然可以使用
这个方法。[注意
:final方法可以被重载]
另外,还有一种被称为
inline(内联)
的机制,当调用一个被声明为final的方法时,直接将方法主体插入到调用处
,而不是进行方法调用(类似于C++中的inline),这样做可以提高程序的效率。
案例:
/*** 父类*/
public class Father {/*** 编写一个final方法*/public final void doAction(){System.out.println("我是final方法、我不可以被重写,但是你可以用噢!渣女!!");}
}
子类试图重写final方法【编译报错
】
/*** 子类*/
public class Children extends Father {public final void doAction(){ //编译报错、因为父类doAction方法是final类型的,所以不可以被重写}public static void main(String[] args) {}
}
使用父类中的final方法【编译通过
】
/*** 子类*/
public class Children extends Father {public static void main(String[] args) {Children children = new Children();children.doAction();}
}
输出:
我是final方法、我不可以被重写,但是你可以用噢!渣女!!
子类重载父类中的final方法
/*** 子类*/
public class Children extends Father {/*** 重写父类中被声明为final的方法* @param a* @param b*/public final void doAction(int a,int b){ // 可以被重载,哈哈,被我发现了System.out.println("a:"+a);System.out.println("b:"+b);}public static void main(String[] args) {Children children = new Children();children.doAction(20,30);}
}
输出:
a:20
b:30
final参数
用来表示这个
参数
在这个函数内部
不允许被修改
案例:
public class FinalTest {/*** 编写一个带参数为final的方法** @param name*//*public void doActionFinal(final String name) {name = "我想修改name,但是编译报错了,难过!!"; //编译不通过}*//*** 编写一个带非final参数的方法** @param name*/public void doAction(String name) {System.out.println("修改前:" + name);name = "name参数不是final的,我修改成功了,一个字:巴适!"; //编译通过System.out.println("修改后: " + name);}public static void main(String[] args) {FinalTest test = new FinalTest();//test.doActionFinal("BreezAm");test.doAction("BreezAm");}
}
输出:
修改前:BreezAm
修改后: name参数不是final的,我修改成功了,一个字:巴适!
final类
当一个类被声明为final时,此类
不能被继承
,所有的方法都不能被重写
。但这并不表示final类的成员变量也是不可变的,要想做到final类的成员变量不可改变,必须给成员变量增加final修饰
。注意:一个类不能即被声明为abstract,又被声明为final【抽象类不能声明为final
】。
试图继承被声明为final的类【编译失败
】
/*** 父类*/
public final class Father {}
/*** 子类*/
public class Children extends Father { //编译报错}
试图将一个abstract类声明为final【编译失败
】
/*** 父类*/
public final abstract class Father { //编译失败,抽象类不能声明为final}
修改final类的成员变量
/*** 父类*/
public final class Father {private String name = "BreezAm";private final int num = 2018010110;public void doAction() {name = "清风";//修改final类的非final成员变量 编译通过num = 2019010110;//修改final类的final成员变量 编译失败}
}
深入解析final关键字的用法相关推荐
- java final char_java基本数据类型总结 类型转换 final关键字的用法
java基本数据类型总结 Java数据类型总结 数据类型在计算机语言里面,是对内存位置的一个抽象表达方式,可以理解为针对内存的一种抽象的表达方式.接触每种语言的时候,都会存在数据类型的认识,有复杂的. ...
- 方法对象java final关键字的用法
之前一直在查找方法对象之类的问题,今天正好有机会和大家讨论一下. 1.用final关键字设置常数 很多程序设计语言都有自己的方法告知编译器某个数据是"常数".常数重要应用于下述两个 ...
- java final定义_Java中final关键字的用法
final在Java中并不常用,然而它却为我们提供了诸如在C语言中定义常量的功能,不仅如此,final还可以让你控制你的成员.方法或者是一个类是否可被覆写或继承等功能,这些特点使final在Java中 ...
- 【Java基本功】一文读懂final关键字的用法
本文主要介绍了final关键字的基本使用方法及原理 final关键字可以修饰类.方法和引用. 修饰类,该类不能被继承.并且这个类的对象在堆中分配内存后地址不可变. 修饰方法,方法不能被子类重写. 修饰 ...
- 【Java基本功】一文读懂final关键字的用法 1
本文主要介绍了final关键字的基本使用方法及原理 final关键字可以修饰类.方法和引用. 修饰类,该类不能被继承.并且这个类的对象在堆中分配内存后地址不可变. 修饰方法,方法不能被子类重写. 修饰 ...
- java抽象类与final关键字的用法
抽象类:使用abstract关键字定义的类就是抽象类 很多具有相同特征和行为的 对象 可以抽象成一个 类 很多具有相同 特征和行为的 类 可以抽象成一个 抽象类 抽象 ...
- java中final double_举例讲解Java中final关键字的用法
1. final variable final variable 就是一个常量,一旦被初始化就不可以被改变. class Test1 { final double PI = 3.14; //常量的名称 ...
- java中final关键字的用法
final:adj. 最终的,不可改变的 我们就取其字面意思"不可改变的". final可以修饰类.方法.变量.那么分别是什么作用呢? (1)修饰类:表示类不可被继承 (2)修饰方 ...
- Android源码中final关键字的用法及final,finally,finalize的区别
Android开发的学习流程 final,finally,finalize的区别 Android的发展越来越快,Android开发人员越来越多,当两种情况碰撞,在诸多开发者中跟紧Android步伐脱颖 ...
最新文章
- 37、C++ Primer 4th笔记,特殊工具与技术,类成员指针
- eBPF内核探测中将任意系统调用转换成事件
- cics oracle xad_Cics安装与配置
- 如何让以特定字符串结尾的所有站点都被加入到Local Intranet Zone中?
- 下取整函数的含义_Excel将3.14159取值为3.15或3.1415? 两个函数为你效劳,拿走不谢...
- LOJ - #117. 有源汇有上下界最小流(有源汇有上下界的最小流)
- bitnami-redmine Apache服务启动不起来
- 说说 Spring AOP 原理
- a标签点击跳转失效--IE6、7的奇葩bug
- 章二测试 1613999388
- windows下编译64位程序时没有没_WIN32定义
- 模糊搜索cell效果
- HDU2001 计算两点间的距离【入门】
- 2.安装 Android SDK
- 基于android的备忘录_[译] 我个人的 Git 技巧备忘录
- 入门人工智能历程,学习西瓜书的体验心得
- 【Python】获取数组中非零元素
- 【BJOI2019】勘破神机(下降幂转自然幂)(第一类斯特林数)(特征方程)
- 机型增多,时间延长,华为一口价更换原装电池活动惊喜不断
- Django+redis+celery实现异步任务