参考链接: Java中的final数组 | Final arrays

1、final变量

final关键字可用于变量声明,一旦该变量被设定,就不可以再改变该变量的值。通常,由final定义的变量为常量。例如,在类中定义PI值,可以使用如下语句:

final double PI=3.14;

在Java中定义全局常量,通常使用public static final修饰,这样的常量只能在定义是被赋值。

public static final double PI_VAULE = 3.14;

规范:被定义为final的常量定义时需要使用大写字母命名,并且中间使用下划线进行连接。

常量示例:

import java.util.Random;

class Test

{

int i = 0;

}

/**

* 常量示例

*

* @author pan_junbiao

*

*/

public class FinalData

{

static Random rand = new Random();

private final int VALUE_1 = 9; // 声明一个final常量

private static final int VALUE_2 = 10; // 声明一个final、static常量

private final Test test = new Test(); // 声明一个final引用

private Test test2 = new Test(); // 声明一个不是final的引用

private final int[] a = { 1, 2, 3, 4, 5, 6 }; // 声明一个定义为final的数组

private final int i4 = rand.nextInt(20);

private static final int i5 = rand.nextInt(20);

public String toString()

{

return "i4值:" + i4 + " i5值:" + i5 + " ";

}

public static void main(String[] args)

{

FinalData data = new FinalData();

// 报错:不能改变定义为final的常量值

// data.VALUE_1 = 8;

// 报错:不能改变定义为final的常量值

// data.VALUE_2 = 9;

// 报错:不能将定义为final的引用指向其他引用

// data.test = new Test();

// 正确: 可以对指定为final的引用中的成员变量赋值

data.test.i = 1;

// 正确: 可以将没有定义为final的引用指向其他引用

data.test2 = new Test();

// 报错:不能对定义为final的数组赋值

// int b[] = { 7, 8, 9 };

// data.a = b;

// 但是final的数组中的每一项内容是可以改变的

for (int i = 0; i < data.a.length; i++)

{

data.a[i] = 9;

}

System.out.println(data);

System.out.println("data2");

System.out.println(new FinalData());

}

}

执行结果:

从上述执行结果中可以发现i5的值是相同的。

全局常量:

我们知道一个被定义为final的对象引用只能指向唯一一个对象,不可以将它再指向其它对象,但是一个对象的值却是可以改变的,那么为了使一个常量真正做到不可更改,可以将常量声明为static final。

示例:在项目中创建FinalStaticData类,在该类中创建Random类的对象,在主方法中分别输出类中定义的final变量a1与a2。

import static java.lang.System.out;

import java.util.Random;

/**

* FinalStaticData类

*

* @author pan_junbiao

*

*/

public class FinalStaticData

{

private static Random rand = new Random(); // 实例化一个Random类对象

// 随机产生0~10之间的随机数赋予定义为final的a1

private final int a1 = rand.nextInt(10);

// 随机产生0~10之间的随机数赋予定义为static final的a2

private static final int a2 = rand.nextInt(10);

public static void main(String[] args)

{

FinalStaticData fdata = new FinalStaticData(); // 实例化一个对象

// 调用定义为final的a1

out.println("重新实例化对象调用a1的值:" + fdata.a1);

// 调用定义为static final的a2

out.println("重新实例化对象调用a2的值:" + fdata.a2);

// 实例化另外一个对象

FinalStaticData fdata2 = new FinalStaticData();

out.println("重新实例化对象调用a1的值:" + fdata2.a1);

out.println("重新实例化对象调用a2的值:" + fdata2.a2);

}

}

运行结果:

从本示例运行结果中可以看出,定义为final的常量不是恒定不变的,将随机数赋予定义为final的常量,可以做到每次运行程序时改变a1的值。但是a2与a1不同,由于它被声明为static final形式,所以在内存中为a2开辟了一个恒定不变的区域,当再次实例化一个FinalStaticData对象时,仍然指向a2这块内存区域,所以a2的值保存不变。a2是在装载时被初始化,而不是每次创建新对象时被初始化;而a1会重新实例化对象时被更改。

最后总结一下在程序中final数据可以出现的位置,如下程序。

/**

* 总结一下在程序中final数据可以出现的位置

*

* @author pan_junbiao

*

*/

public class FinalDataTest

{

// final成员变量不可更改

final int VALUE_ONE = 6;

// 在声明final成员变量时没有赋值,称为空白final

final int BLANK_FINALVAULE;

// 在构造方法中为空白final赋值

public FinalDataTest()

{

BLANK_FINALVAULE = 8;

}

// 设置final参数,不可以改变参数x的值

int doIt(final int x)

{

return x + 1;

}

// 局部变量定义为final,不可以改变i的值

void doSomething()

{

final int i = 7;

}

}

2、final方法

首先,我们应该了解定义为final的方法不能被重写。

将方法定义为final类型可以防止任何子类修改该类的定义与实现方式,同时定义为final的方法执行效率要高于非final方法。在修饰权限中曾经提到过private修饰符,如果一个父类的某个方法被设置为private修饰符,子类将无法访问该方法,自然无法覆盖该方法,所以一个定义为private的方法隐式被指定为final类型,这样无须将一个定义为private的方法再定义为final类型。

语法:

private final void test()

{

}

3、final类

定义为final的类不能被继承。

如果希望一个类不允许任何类继承,并且不允许其他人对这个类有任何改动,可以将这个类设置为final形式。

final类的语法如下:

final 类名{}

如果将某个类设置为final形式,则类中的所有方法都被隐式设置为final形式,但是final类中的成员变量可以被定义为final或非final形式。

示例:在项目中创建FinalClass类,在类中定义doit()方法和变量a,实现在主方法中操作变量a自增。

/**

* 定义final类

*

* @author pan_junbiao

*

*/

final class FinalClass

{

int a = 3;

void doit()

{

}

public static void main(String args[])

{

FinalClass f = new FinalClass();

f.a++;

System.out.println(f.a); // 结果:4

}

}

4、总结

下面总结了一些使用final关键字的好处:

(1)final关键字提高了性能。JVM和Java应用都会缓存final变量。

(2)final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。

(3)使用final关键字,JVM会对方法、变量及类进行优化。

不可变类:

创建不可变类要使用final关键字。不可变类是指它的对象一旦被创建了就不能被更改了。String是不可变类的代表。不可变类有很多好处,譬如它们的对象是只读的,可以在多线程环境下安全的共享,不用额外的同步开销等等。

关于final的重要知识点:

(1)final关键字可以用于成员变量、本地变量、方法以及类。

(2)final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。

(3) 你不能够对final变量再次赋值。

(4)本地变量必须在声明时赋值。

(5)在匿名类中所有变量都必须是final变量。

(6)final方法不能被重写。

(7)final类不能被继承。

(8)final关键字不同于finally关键字,后者用于异常处理。

(9)final关键字容易与finalize()方法搞混,后者是在Object类中定义的方法,是在垃圾回收之前被JVM调用的方法。

(10)接口中声明的所有变量本身是final的。

(11)final和abstract这两个关键字是反相关的,final类就不可能是abstract的。

(12)final方法在编译阶段绑定,称为静态绑定(static binding)。

(13)没有在声明时初始化final变量的称为空白final变量(blank final variable),它们必须在构造器中初始化,或者调用this()初始化。不这么做的话,编译器会报错“final变量(变量名)需要进行初始化”。

(14)将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化。

(15)按照Java代码惯例,final变量就是常量,而且通常常量名要大写。

[转载] Java中的final变量、final方法和final类相关推荐

  1. Java中的PrintWriter的write方法和print方法的区别是什么?

    参考:https://www.zhihu.com/question/511719621

  2. Java中static、this、super、final用法

    一.static 请先看下面这段程序: public class Hello{ public static void main(String[] args){ //(1) System.out.pri ...

  3. [转载] Java中变量与常量

    参考链接: Java中的实例变量隐藏 1.变量的定义:定义变量就是要告诉编译器这个变量的数据类型,这样编译器才知道需要分配多少空间给它,以及它能存放什么样的数据.在程序运行过程中空间的值是变化的,这个 ...

  4. [转载] Java中的变量和常量

    参考链接: Java中的变量范围 在程序中存在大量的数据来代表程序的状态,其中有些数据在程序的运行过程中值会发生改变,有些数据在程序运行过程中值不能发生改变,这些数据在程序中分别被叫做变量和常量. 在 ...

  5. Java中的宏变量,宏替换详解。

    转载自 Java中的宏变量,宏替换详解. 群友在微信群讨论的一个话题,有点意思,特拿出来分享一下. 输出true false 来看下面这段程序,和群友分享的大致一样. public static vo ...

  6. [转载] Java中如何引用另一个类里的集合_Java工程师面试题整理

    参考链接: 在Java中将预定义的类名用作类或变量名 花了一星期把学过的都整理一遍 尽量易懂,从基础到框架 最新版大厂面经汇总出炉,持续更新中 汇总完了上传网盘,设计到后端架构师的一切知识 如果没更新 ...

  7. 【Groovy】Groovy 动态语言特性 ( Groovy 中的变量自动类型推断以及动态调用 | Java 中必须为变量指定其类型 )

    文章目录 前言 一.Groovy 动态语言 二.Groovy 中的变量自动类型推断及动态调用 三.Java 中必须为变量指定其类型 前言 Groovy 是动态语言 , Java 是静态语言 ; 一.G ...

  8. 非静态方法可以访问Java中的静态变量/方法吗?

    "非静态方法可以访问静态变量或调用静态方法"是Java中有关静态修饰符的常见问题之一,答案是, 是的 ,非静态方法可以访问静态变量或调用静态方法. Java中的方法. 这没有问题, ...

  9. java中的实例变量

    简介 在类的声明中,属性是用变量来表示的.这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的.类的每个对象维护它自己的一份实例变量的副本. java中的实例变量 含义: 实例变量 ...

最新文章

  1. 利用cmake查看OpenCV的源码的方法
  2. sdut 1028 Catch That Cow( BFS)
  3. html5中标签分为,HTML标签的三种类型
  4. 2021牛客暑期多校训练营7 K-xay loves sequence(主席树+二分)
  5. 为Openstack制作CentOS7镜像
  6. BMW M550i xDrive
  7. ECharts实操手册
  8. Matlab中的有限域计算
  9. 苹果计算机怎样恢复桌面,mac桌面整理_使Mac桌面恢复整洁的四种技巧
  10. choco 代理强制失效方法
  11. unity简单实现融合树动画
  12. 求解线性同余方程--扩展欧几里得
  13. 避暑山庄消失的三十六景,曾经那么美!
  14. python数据分析六个环节_安利6个珍藏的Python数据分析神器
  15. 【08月20日】A股滚动市净率PB历史新低排名
  16. 利用 a 标签 实现 下载图片(不是打开)的正确姿势
  17. Jenkins密码忘记重置方法
  18. 算法题 —— 寻找明星
  19. SDUT 3929 魔戒
  20. Leetcode 334.递增的三元子序列

热门文章

  1. 让div垂直以及水平居中浏览器窗口
  2. 一个android工程生成两个aar,android studio生成aar包并在其他工程引用aar包(示例代码)...
  3. PyTorch中的torch.nn.Parameter() 详解
  4. memcpy和memmove的区别以及内存重叠问题
  5. 海南大学计算机原理,海南大学微机原理课件 第一章 计算机基础知识
  6. wireshark网卡权限_网络分析系列之六_Wireshark安装
  7. 你用计算机做过什么事情,他偷偷干了什么?(电脑)
  8. Problem E: 建立链表(线性表)
  9. HDU1284——钱币兑换问题【dp】
  10. Flutter 使用动画播放一组图片