[转载] Java中的final变量、final方法和final类

参考链接: 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变量就是常量,而且通常常量名要大写。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540179.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux基础篇_01_计算机概论

学习资料&#xff1a;《鸟哥的Linux私房菜&#xff08;基础篇&#xff09;》部分&#xff1a;Linux的规划与安装 时间&#xff1a;20130225 学习笔记&#xff1a;计算机定义&#xff1a;接受使用者输入指令与数据&#xff0c; 经由中央处理器的数学与逻辑单元运算处理后&#x…

[转载] java中的经典问题:传值与传引用

参考链接&#xff1a; 有关Java中数组分配的有趣事实 参数传递的秘密 知道方法参数如何传递吗&#xff1f; 记得刚开始学编程那会儿&#xff0c;老师教导&#xff0c;所谓参数&#xff0c;有形式参数和实际参数之分&#xff0c;参数列表中写的那些东西都叫形式参数&#x…

[3/21]Windows Server 2008时钟方面的改进展示

在Windows Server 2008中的时钟显示和以往Windows Server 2003及以前的版本显示有很大的差别。如果要显示并进行简单的时间修改可以在时钟上双击&#xff0c;会出现如下图所示的界面。在上图中可以调整但无法进行真正的修改&#xff0c;彻底修改需要点击&#xff02;更改日期和…

[转载] 黑马程序员_学习笔记8_C#基础归纳之数组

参考链接&#xff1a; Java中的锯齿数组Jagged array ---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流&#xff01; ---------------------- 什么是数组&#xff1f; 数组是一组数据结构&#xff0c;它可以包含同一类型的多个元素。C#用特殊记号还…

2Python全栈之路系列之MysQl基本数据类型

Python全栈之路系列之MySQL基本数据类型 MySQL中定义数据字段的类型对你数据库的优化是非常重要的。 MySQL支持多种类型&#xff0c;大致可以分为三类&#xff1a; 数字类型 日期和时间类型 字符串类型 数字类型 类型大小用途BIT-二进制TINYINT1字节小整数值INT or INTEGER4字…

[转载] JAVA笔记_(Day04,Day05)函数数组

参考链接&#xff1a; 了解Java中的数组IndexOutofbounds异常 文章目录 函数定义练习误区重载&#xff08;overload&#xff09;重载选择题练习函数的内存调用问题 数组定义数组的内存图解数组的常见问题应用求和最大值将数组转成字符串查表法转十六进制查表版&#xff08;十六…

VDI序曲二 RemotoAPP部署

首先&#xff0c;我们需要准备如下角色&#xff1a;沿用VDI序曲一的2台物理服务器以及角色我们在物理服务器1的hyper-v上&#xff0c;我们利用之前我介绍的“服务器虚拟化之准备母盘VHD”的方法再创建如下虚拟机&#xff1a;WIN-RDAPP&#xff1b;WIN-RDWA&#xff1b;WIN-RDCB…

[转载] Java ArrayList toArray(T[] a) 解惑

参考链接&#xff1a; Java中的Array vs ArrayList 先看一个小的代码片段 ArrayList<Integer> arrayList new ArrayList<>(); Collections.addAll(arrayList, 11, 21, 31, 41, 51); Integer[] a new Integer[0]; Integer[] b new Integer[arrayList.size()]; …

CentOS7使用firewalld打开关闭防火墙与端口(转载)

1、firewalld的基本使用 启动&#xff1a; systemctl start firewalld 查看状态&#xff1a; systemctl status firewalld 停止&#xff1a; systemctl disable firewalld 禁用&#xff1a; systemctl stop firewalld 2.systemctl是CentOS7的服务管理工具中主要的工具&#xff…

多任务管理类 MutilTaskManager

计算和计算所需的数据能被较为平均的非配到若干task的时候&#xff0c;下面的任务管理类可以提供在大数据大计算量的情况下非精确的控制task的执行数量来限制计算量和内存占用量.下面是代码&#xff08;非线程安全版本&#xff09;&#xff1a; public class MutilTaskManager{…

[转载] Scanner和bufferreader读取控制台字符的区别

参考链接&#xff1a; Java中Scanner和BufferReader类之间的区别 从开始学习Java就用了scanner&#xff0c;因为比较简单每当遇到空格键或者换行键则读取下一个字符&#xff0c;一般用法 while(input.hasNextInt()){ int n input.nextInt(); int t input.nextInt(); int c …

Node.js meitulu图片批量下载爬虫1.051

原有1.05版程序没有断点续传模式&#xff0c;现在在最近程序基础上改写一版1.051. // // meitulu图片批量下载爬虫1.051 // 用最近的断点续传框架改写原有1.05版程序 // 2017年11月21日 //// 内置https模块 var httpsrequire("https");// 内置http模块 var httprequi…

[转载] Java实现归并排序(超详细,新手请进)

参考链接&#xff1a; Java中将数组合并为的新数组 归并排序 大家好&#xff0c;这是我第一次在CSDN上写东西&#xff0c;因为我一直觉得有需要就去找别人的blog看看就好&#xff0c;但我发现自己写出来的东西确实能加深记忆。我半路出家&#xff0c;属实是个菜鸟&#xff0…

centos6设置静态IP

#编辑配置文件,添加修改以下内容 vim /etc/sysconfig/network-scripts/ifcfg-eth0 BOOTPROTOstatic #启用静态IP地址 ONBOOTyes #开启开机自动启用网络连接 IPADDR192.168.21.129 #设置IP地址 NETMASK255.255.255.0 #设置子网掩码 GATEWAY192.168…

[转载] 1022 D进制的A+B (20分)【java题解】【80ms】

参考链接&#xff1a; Java流Stream 题解 使用 toUnsignedString&#xff08;&#xff09;即可 我有仔细读过toUnsignedString&#xff08;&#xff09;&#xff0c;有兴趣可以看看 第3章 java的基本程序设计结构【补缺学习】【注释与数据类型】【核心技术卷I】 impor…

mysql 5.6.4以上版本innodb支持全文索引的测试

对于mysql 5.6.4以上版本innodb支持全文索引的测试 在mysql官网&#xff0c;innodb引擎在5.6.4版本提供了对全文索引的支持&#xff0c;笔者对此做了测试&#xff0c;发现对中文全文检索的支持依然不理想&#xff0c;但却确实提供了对英文的全文支持。 12.9.5 Full-Text Restri…

[转载] Java字符串分割方法

参考链接&#xff1a; Java中的StringTokenizer方法的示例 2 [sizemedium]1.用split()方法进行分割&#xff0c;分割开的子字符串放入数组&#xff0c;然后进行处理。 示例代码如下&#xff1a; public class SplitTest { /** * param args * author colin */ …

[转载] Java StringBuilder StringJoiner

参考链接&#xff1a; 何时在StringBuilder上使用StringJoiner 1. StringBuilder Java编译器对String做了特殊处理&#xff0c;使得我们可以直接用拼接字符串。 虽然可以直接拼接字符串&#xff0c;但是&#xff0c;在循环中&#xff0c;每次循环都会创建新的字符串对象&a…

EMC VMAX的磁盘构成,fast policy(重要)

首先是流程&#xff0c; 不同种类的磁盘&#xff08;sata&#xff0c;fc&#xff0c;flah&#xff09;->disk group->raid->DATA volume->thin pool->TDEV and BCVDEV (lun) 然后细看&#xff1a; 1&#xff09; 不同种类的磁盘叫做disk&#xff0c;这是可见的物…