首页 > 编程语言 >Java并发——final

Java并发——final

时间:2023-01-31 17:03:16浏览次数:52  
标签:Java String 对象 并发 修饰 方法 final 变量

什么是不变性(Immutable)

  • 如果对象在被创建后,状态就不能被修改,那么它就是不可变的
  • 具有不变性的对象一定是线程安全的,我们不需要对其采取任何额外的安全措施,也能保证线程安全

final

  • 在java中,final可以用来修饰类,方法和变量(成员变量或局部变量)。

final的作用

  • 早期:早期的Java实现版本中,会将final方法转为内嵌调用
  • 现在:类防止被继承、方法防止被重写、变量防止被修改,天生是线程安全的,而不需要额外的同步开销

修饰方法

  • final不可以修饰构造方法
  • 静态方法也不可以被重写 使用final方法的原因主要有两个:
  • 1、把方法锁定,以防止继承类对其进行更改。
  • 2、效率,在早期的java版本中,会将final方法转为内嵌调用。但若方法过于庞大,可能在性能上不会有多大提升。因此在最近版本中,不需要final方法进行这些优化了。
  • final方法意味着“最后的、最终的”含义,即此方法不能被重写。

注意:若父类中final方法的访问权限为private,将导致子类中不能直接继承该方法,因此,此时可以在子类中定义相同方法名的函数,此时不会与重写final的矛盾,而是在子类中重新地定义了新方法。

修饰变量

final成员变量表示常量,只能被赋值一次,赋值后其值不再改变。类似于C++中的const。

 

当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。本质上是一回事,因为引用的值是一个地址,final要求值,即地址的值不发生变化。 

 

final修饰一个成员变量(非静态),必须要显示初始化

  • 1、是在变量声明的时候初始化;
  • 2、是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。
  • 3、是在类的初始化代码块中赋值(不常用)

final修饰静态成员变量(静态),也必须要显示初始化

  • 1、是在变量声明的时候初始化
  • 2、在static静态代码块中赋值

final修饰的局部变量

  • 不规定赋值时机,只是要求在使用前赋值

当函数的参数类型声明为final时,说明该参数是只读型的。即你可以读取使用该参数,但是无法改变该参数的值。

修饰类

当用final修饰类的时,表明该类不能被其他类所继承。当我们需要让一个类永远不被继承,此时就可以用final修饰,但要注意:final类中所有的成员方法都会隐式的定义为final方法。

 

在java中,String被设计成final类,那为什么平时使用时,String的值可以被改变呢?

 

字符串常量池是java堆内存中一个特殊的存储区域,当我们建立一个String对象时,假设常量池不存在该字符串,则创建一个,若存在则直接引用已经存在的字符串。当我们对String对象值改变的时候,例如 String a="A"; a="B" 。a是String对象的一个引用(我们这里所说的String对象其实是指字符串常量),当a=“B”执行时,并不是原本String对象("A")发生改变,而是创建一个新的对象("B"),令a引用它。

final注意点:

  • final修饰对象的时候,只是对象应用不可变,而对象本身的属性是可以变化的
  • final使用原则:良好的编程习惯

不变性和final的关系

  • 不变性并不意味着,简单的用final修饰就是不可变的
    • 对于基本数据类型,确实被final修饰后就具有不可变性
    • 但是对于对象类型,需要该对象保证自身被创建后,状态永远不变才可以

满足以下条件时,对象才是不可变的

  • 对象创建后,其状态就不能修改
  • 所有属性都是final修饰的
  • 对象创建过程中没有发生溢出

把变量写在线程内部——栈封闭

  • 在方法里新建的局部变量,实际上是存储在每个线程的私有栈空间的,而每个栈的空间是不能被其他线程所访问的,所以不会有线程安全问题。这就是著名的“栈封闭”技术,是“线程封闭”技术的一种情况

参考: https://www.cnblogs.com/ktao/p/8586966.html

标签:Java,String,对象,并发,修饰,方法,final,变量
From: https://blog.51cto.com/u_14014612/6029789

相关文章

  • Java并发JUC——并发容器
    引言容器是Java基础类库中使用频率最高的一部分,Java集合包中提供了大量的容器类来帮组我们简化开发,我前面的文章中对Java集合包中的关键容器进行过一个系列的分析,但这些集......
  • Java并发JUC——并发流程控制
    什么是并发流程控制控制并发流程的工具类,作用就是帮助我们程序员更容易的让线程之间进行合作让线程之间相互配合,来满足业务需求比如,让现场A等待线程B执行完毕后在执行等......
  • JavaS
    目录前言数据类型变量声明注释输出函数字符串运算if条件判断switch条件判断循环语句数组对象函数前言数据类型number:数字型,包括整数和小数boolean:布......
  • Java并发——ThreadLocal详解
    引言ThreadLocal的官方API解释为:“该类提供了线程局部(thread-local)变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其get或set方法)的每个线程都有自己......
  • jmeter压力测试动态修改并发参数
    https://blog.csdn.net/weixin_45131345/article/details/117412808#:~:text=%E4%B8%BA%E4%BA%86%E6%8C%89%E6%8C%87%E5%AE%9A%E6%97%B6%E9%95%BF%E6%89%A7%E8%A1%8C%EF%BC......
  • java:分数-------简(Math类)
    Math类Math类中包含E和PI两个静态常量,正如它们名字所暗示的,它们的值分别等于e(自然对数)和π(圆周率)。例1调用Math类的E和PI两个常量,并将结果输出。......
  • Java concurrent并发工具包用户手册
    译序本指南根据JakobJenkov最新博客翻译,请随时关注博客更新:http://tutorials.jenkov.com/java-util-concurrent/index.html。本指南已做成中英文对照阅读版的pdf文档......
  • springboot,java,activiti实现流程审批(支持单体、微服务融合)
    前言activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,请假审批demo从流程绘制到审批结束实例。一、项目形式springboot+vue+activiti集成了activiti......
  • 带你熟悉3种AQS的线程并发工具的用法
    摘要:AQS的全称为(AbstractQueuedSynchronizer),AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器。本文分享自华为云社区《【高并......
  • 如何通过Java应用程序添加或删除 PDF 中的附件
    当我们在制作PDF文件或者PPT演示文稿的时候,为了让自己的文件更全面详细,就会在文件中添加附件。并且将相关文档附加到PDF可以方便文档的集中管理和传输。那么如何添加或删......