再说final变量

Java中的final变量 final修饰变量 final修饰方法 final修饰类 final和String的关系 在开发的过程中,经常会使用String类来处理字符串相关的数据,但今天去看String源代码时,发现这个类是用final修饰的,于是,决定去探究inal关键字。final关键字可以修改类,方法和属性,但这个关键字的作用是什么?文章可以带你了解。... 阅读详情

转载:http://blog.youkuaiyun.com/axman/article/details/1460544

从jdk1.0到今天,JAVA技术经过十余年的发展,技术上已经发生了巨大的变化.但final变量的定义从它
诞生那天起,就没有发生任何变化,也就是这十多年它就一直表示它原来的意思.

但遗憾的是,经过十多年仍然有90%的人没有理解它的真实含义,也没有一篇文章,包括我所见到的所有介绍
JAVA的书籍(包括TKJ)都没有说清楚,我相信肯定有些作者是理解的,但没有一个作者向读者说清楚.而中国网友
大多数人被一篇胡说八道的<<浅谈Java中final,finalized,finally>>的文章跑过马.(脸红一下:当初我也是).

final变量的定义本身并不复杂,就是变量一经初始化就不能再指向其它对象.在c++中它是一个const指针,而
不是指向const变量的指针,const指针的意思是说它只能一直指向初始化时的那个地址.但那个地址中对象本身
是可以修改的.而指向const变量的指针是说所指对象本身是不能修改的.

如:final StringBuffer sb = new StringBuffer("Axman");
sb = new StringBuffer("Sager");//错误,sb不能再指向其它对象.
sb.append(" was changed!"); //sb指向的地象本身可以修改.

先说final变量初始化:

很多文章都这么说:其初始化可以在两个地方,一是其定义处,二是在构造函数中,两者只能选其一。
胡说八道!
final变量可以在任何可以被始化的地方被始化,但只能被初始化一次.一旦被初始化后就不能再次赋
值(重新指向其它对象),作为成员变量一定要显式初始化,而作为临时变量则可以只定义不初始化(当然也不能引用)
即使是作为一个类中的成员变量,也还可以在初始化块中初始化,所以"其初始化可以在两个地方,一是其定义处,
二是在构造函数中,两者只能选其一"是错误的.


作为成员变量时,final字段可以设计不变类,是不变类的一个必要条件但不是一个充要条件.至少可以保证字段不
会以setXXX()这样的方式来改变.但无法保证字段本身不被修改(除非字段本身也是不变类);

对于方法参数的final变量:
对于方法参数的变量定义为final,90%以上的文章都说"当你在方法中不需要改变作为参数的对象变量时,明确使
用final进行声明,会防止你无意的修改而影响到调用方法外的变量。"
胡说八道!

我不知道这个修改是说重新赋值还是修改对象本身,但无论是哪种情况,上面的说法都是错误的.
如果是说重新赋值,那么:
 public static void test(int[] x){
  x = new int[]{1,2,3};
 }

    int[] out = new int[]{4,5,6};
    test(out);
    System.out.println(out[0]);
    System.out.println(out[1]);
    System.out.println(out[2]);
    调用test(out);无论如何也不会影响到外面变量out.你加不加final根本没有意义.final只会强迫方法内
多声明一个变量名而已,即把x = new int[]{1,2,3};改成int y = new int[]{1,2,3}; 其它没有任何实际意义.
    如果说是修改对象本身:
 public static void test(final int[] x){
  x[0] = 100;
 }
    int[] out = new int[]{4,5,6};
    test(out);
    System.out.println(out[0]);
难道你用final修饰就不可以修改了?所以说对于方法参数中final是为了不影响调用方法外的变量那是胡说八道的.

那我们到底为什么要对参数加上final?其实对方法参数加final和方法内变量加上final的作用是相同的,即为了将它们
传给内部类时保证调用的一致性:

abstract class ABSClass{
 public abstract void m();
}

现在我们来看,如果我要实现一个在一个方法中匿名调用ABSClass.应该:
 public static void test(final String s){
     //或final String s = "axman";
  ABSClass c = new ABSClass(){
   public void m(){
      int x = s.hashCode();

      System.out.println(x);

   }
  };
  //其它代码.
 }

 从代码上看,在一个方法内部定义的内部类的方法访问外部方法内局部变量或方法参数,是非常自然的事,但内部类编译的时候如何获取这个变量,因为内部类除了它的生命周期是在方法内部,其它的方面它就是一个普通类。那么它外面的那个局部变量或方法参数怎么被内部类访问?编译器在实现时实际上是这样的:

 


  public static void test(final String s){
     //或final String s = "axman";

 

  class OuterClass$1 extends ABSClass{

   private final String s;
   public OuterClass$1(String s){
      this.s = s;   
   }
   public void m(){
      int x = s.hashCode();

      System.out.println(x);

   }
  };

  
  ABSClass c = new OuterClass$1(s);
  //其它代码.
 }
即外部类的变量被作为构造方法的参数传给了内部类的私有成员.
假如没有final,那么:
 public static void test(String s){
     //或String s = "axman";
  ABSClass c = new ABSClass(){
   public void m(){
     s = "other";
   }
  };
  System.out.println(s);
 }
 就会编译成:
  public static void test(String s){
     //或String s = "axman";

 

  class OuterClass$1 extends ABSClass{

   private String s;
   public OuterClass$1(String s){
      this.s = s;   
   }
   public void m(){
     s = "other";

   }
  };

   ABSClass c = new OuterClass$1 (s);

  }

 

 内部类的s重新指向"other"并不影响test的参数或外部定义的那个s.同理如果外部的s重新赋值内部类的s也不会跟着改变。
 而你看到的
  public static void test(String s){
     //或String s = "axman";
  ABSClass c = new ABSClass(){
   public void m(){
     s = "other";
   }
  };
  System.out.println(s);
 }

 

 在语法上是一个s,在内部类中被改变了,但结果打印的出来的你认为是同一的s却还是原来的"axman",
 你能接收这样的结果吗?
 所以final从语法上约束了实际上两个不同变量的一致性(表现为同一变量).

【转载】参数估计(Parameter Estimation):频率学派(最大似然估计MLE、最大后验估计MAP)与贝叶斯学派(贝叶斯估计BPE) 基础 频率学派与贝叶斯学派 http://www.douban.com/group/topic/16719644/ http://www.zhihu.com/question/20587681 最大似然估计(Maximum likelihood estimation,MLE) http://baike.baidu.com/view/1918804.htm http://baike.baidu.co 阅读详情

相关推荐

vba 修改下拉列表_Excel联想式下拉菜单制作教程II

?点击关注Excel表哥公众号上期我们分享了Excel联想式下拉菜单制作教程,可以简化大家在下拉菜单过长时的数据录入工作。文章末尾给大家提出了一个问题:为什么下拉列表数据源需要先排序?今天我们继续分享一个不用对数据源排序也能实现的下拉列表制作方法。先看最终的效果动图:今日分享难度指数:★★★★☆01创建辅助列在需要设置下拉列表的工作表中创建一列辅助列,如下图所示:在辅助列F3单元格输入下...

weixin_39593718的博客 1576

java 方法中内部类使用外部变量

Java允许内部类访问外部方法的final或effectively final局部变量。从Java 8开始,即使没有明确声明为final,如果局部变量在初始化之后没有再被赋值,它就被视为effectively final,可以在内部类中使用。要么直接使用final类型的变量,要么就如下定义直接赋值初始值,此时认为是final。

42 580

GNSS气象学入门:从ZTD到PWV的水汽反演全流程解析(含精度评估)

本文详细解析了GNSS气象学中从ZTD到PWV的水汽反演全流程,包括基础概念、反演原理、数据处理步骤及精度评估方法。通过PRIDE软件和MATLAB代码示例,展示了如何高效提取ZTD数据并结合ERA5气象数据进行PWV计算,为气象研究和业务应用提供了实用指南。

weixin_28707365的博客 572

内部类使用final外部变量

内部类访问局部变量的时候,变量必须加上final修饰。局部变量在所处的函数执行完之后就释放了,但是内部类对象如果还有引用指向的话它是还存在的。(不管变量是不是final,他的生命周期都在于{}中), class Outer{ public

fengxiaotao_cool的专栏 343

怎么用phpstudy制作网站

随着实践的深入,你会逐渐掌握更多高级技巧和技术,让你的网站变得更加完善和吸引人。现在你已经成功设置了你的本地Web服务器环境,接下来我们将指导你如何利用这个环境来创建一个简单的PHP网页项目。为了使网站更加动态且功能丰富,我们需要学会如何让PHP脚本与MySQL数据库交互。为了让网站看起来更专业美观,可以考虑引入CSS样式表来定制网页布局及视觉效果。当你对本地开发的网站感到满意后,下一步就是将其发布到互联网上供他人访问了。让我们进一步扩展我们的网站,加入一个简单的用户注册与登录系统。

2401_87999399的博客 6573

Xilinx Aurora 8B/10B IP核详解和仿真

Xilinx Aurora 8b/10b IP核的详解,以及使用与仿真示例,对IP核的配置和如何仿真有非常详细的说明,除了对IP核官方文档的内容进行了解析以外,还对GTX引脚的选择等比较容易混淆和不好理解的地方进行了说明。最后对IP核的仿真运行进行了STEP BY STEP 的说明,对仿真的结果也进行了简要的说明。 该文档对Xilinx FPGA和ZYNQ SOC下 AURORA 8B/10B IP核的使用提供了一个快速上手的指导。

weixin_43354598的博客 1万+

Java内部类引用外部类中的局部变量为何必须是final问题解析

今天编写一个多线程程序,发现在方法内定义内部类时,如果内部类调用了方法中的变量,那么该变量必须申明为final类型,百思不得其解,后来想到应该是生命周期的原因,因为方法内定义的变量是局部变量,离开该方法,变量就失去了作用,也就会自动被消除,而内部类却不会离开它所在方法就失去作用,它有更广的生命周期,下面通过一个实例加以说明:     如例中所示,在外部类Outer中声明了

且听风吟的专栏 1万+

解决Keil uVision许可证管理中Unknown Product错误

嵌入式开发中,IDE工具的许可证管理是确保开发环境正常运行的关键环节。Keil uVision作为ARM架构的主流开发工具,其许可证系统采用加密验证机制,通过产品版本识别实现授权控制。当出现Unknown Product错误时,通常源于版本兼容性问题或区域发行版差异,这直接影响开发工具链的可用性。特别是在维护历史项目或使用中国特供版时,开发者常会遇到此类问题。通过分析许可证类型、调整安装配置或建立虚拟化开发环境等工程实践方案,可以有效解决这类授权验证故障,保障嵌入式项目的持续集成与交付效率。

weixin_33743248的博客 363

内部类使用外部类局部变量必须是 final 原因

javac工具在编译的时候会做一些处理,具体会在Inner类里存储一份outer变量的拷贝,Inner类里看得见的实际使用outer的地方,实际上只是用的这个拷贝。 而问题是这个拷贝过程只在Inner类定义时进行一次,如果我们在Inner类定义完后的其他地方改变了outer变量,并不会反应在这份拷贝上面。所以为了防止这种不一致的发生,就用强制给outer变量加final修饰符的方式,把上面

MAIMIHO的博客 918

【城市数据集】世界城市数据库和访问门户工具WUDAPT

简介世界城市数据库和访问门户工具WUDAPT

WW、forever的博客 1284

论文翻译:Automatic Lesson Plan Generation via Large Language Models with Self-critique Prompting

在本文中,我们利用大型语言模型(LLMs)的理解和生成能力来自动生成定制化的课程计划。这解决了传统计划可能无法充分满足不同教学环境和学生群体的特定需求的常见挑战。我们提出了一个新颖的三阶段过程,包括使用检索增强生成(RAG)逐步生成课程计划的每个关键组成部分,通过LLMs进行自我批评,以及随后的细化。我们使用这种方法为小学2至5年级生成了涵盖80多个主题的数学课程计划。邀请了三位经验丰富的教育工作者制定全面的课程计划评估标准,然后使用这些标准将我们的LLM生成的课程计划与同一主题的实际课程计划进行基准比较。

CSPhD-winston的博客 1100

Java final变量、final方法、final类

一、final变量 咋们先看个,例子,再来解释为什么会这样! public class Main { public static void main(String[] args) { // write your code her final int a[]=new int[2]; final int b=1; a[0]=1; ...

Cheney的博客 1316

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Java中final和static修饰的变量是在什么时候赋值的?

开始一位朋友在群里问了这样一个问题:本着乐于助人的想法,我当时给出的回答:后来我总觉得哪里不对劲。于是我仔细翻阅了《Java虚拟机规范》和《深入理解Java虚拟机》关于这一部分的内容。害...

程序IT圈 5981

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

final变量

final成员变量final修饰的成员变量必须由程序员显示地指定初始值。对于final修饰的 成员变量而言,一旦有了初始值,就不能被重新赋值,如果既没有在定义成员变量时指定初始值,也没有在初始化块、构造器中为成员变量指定初始值,那么这些成员变量的值将一直是系统默认的初始值,没有意义。final修饰变量规则如下。类变量:必须在静态初始化块中指定初始值或声明该变量时指定初始值,而且只能在两个地方的其中之

衣带渐宽终不悔,为伊消得人憔悴。 359

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

java的final变量

java的final变量

听海边涛声 1517

final修饰变量

前言:因为部门的需要,这段时间在招人,在和候选者沟通的时候,我发现一些人对于一个问题:变量被final修饰时它是不可变的,这个普遍的说法并不是十分的清楚本质,那就是----不变性究竟是指的什么是不变的。所以,才有了我今天这篇文章,希望可以给对这个问题不明白的人一些帮助。 好了,final修饰的变量究竟是怎么个不变性呢,这就开始进入主题吧。。。 很多人对于一个问题总是最关注简单直

蒙的博客 1万+

Java中的final变量、final方法和final类

1、final变量 final关键字可用于变量声明,一旦该变量被设定,就不可以再改变该变量的值。通常,由final定义的变量为常量。例如,在类中定义PI值,可以使用如下语句: final double PI=3.14; 在Java中定义全局常量,通常使用public static final修饰,这样的常量只能在定义是被赋值。 public static final double PI_VAULE = 3.14; 规范:被定义为final的常量定义时需要使用大写字母命名,并且中间使用下划线进行连接。 常

yygr的博客 3968

Java之final修饰变量

final修饰的实例变量 被final修饰的实例变量必须显示指定初始值,而且只能在如下3个位置指定初始值: 1.定义final实例变量时指定初始值; 2.在非静态初始化块中为final实例变量指定初始值 3.在构造器中为final实例变量指定初始值 对于普通实例变量,Java程序可以对它执行默认的初始化,也就是将实力变量的值指定为默认的初始值0或null,

伪文艺编程妞 4956

局部变量 final Java_为什么在Lambdas中使用的局部变量必须是Final或有效Final

为什么在Lambdas中使用的局部变量必须是Final或有效Final1. 介绍Java 8提供了lambda表达式,并通过关联给出了有效final变量的概念。是否想知道为什么在lambdas中捕获的局部变量必须是final或有效的final?JLS给了我们一些提示,它说对有效final变量的限制禁止对动态更改的本地变量的访问,捕获本地变量可能会引入并发问题。但是,这是什么意思呢?在下一节中,我们...

weixin_31170085的博客 3765

java学习之路:27.final变量,final方法,final类

final关键字定义的变量必须在声明时对其进行赋值操作,final除了可以修饰基本数组类型的常量,还可以修饰对象引用。一旦一个对象引用被修饰为final后,它只能恒定指向一个对象,无法将其改变以指向另一个对象。 一个即是static又是final的字段值占据一段不能改变的存储空间。 在Java中定义全局常量,通常使用public static final修饰,这样的常量只能在定义是被赋值。

花狗Fdog的博客 1680

被final修饰的变量在哪存储_final知识点总结

  final从字面上理解含义为“最后的,最终的”。在Java中也同样表示出此种含义。  final可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。一、 final修饰类:  final修饰类即表示此类已经是“最后的、最终的”含义。因此,用final修饰的类不能被继承,即不能拥有自己的子类。  如果试图对一个已经用final修饰的类进行继承,在...

weixin_39604819的博客 3512

关于java8 stream中需要使用final变量的思考

关于java8 stream中需要使用final变量的思考关于final的使用final 变量final 方法final 类关于不能使用final的解释 关于final的使用 final 变量 final 限制的变量可以是基础数据类型和引用数据类型 基本数据类型:内容不可变 引用数据类型:引用的指向不可变,执行的对象的值可以改变。例如 public static void main(String[...

yanjy1993的博客 7388

final成员变量与final局部变量

final修饰符 final关键字可以修饰类、变量和方法 final修饰的变量,一旦该变量被赋予初始值,以后则不能改变(即获得初始值之后不能被重新赋值);final可以修饰成员变量(实际变量、类变量)、局部变量、形参。 final成员变量 final修饰的成员变量必须由程序员显示的指定初始值; final修饰的类变量:必须在静态初始化块中指定初始值或声明该变量时指定初始值,并且只能在其中一个地方指...

qq_42334879的博客 685

【Java】final变量、final方法、final类

1、final变量

Fanjufei的博客 1774
上一篇: ORM技术概念与实例
下一篇: Hibernate关联关系配置(一对多、一对一和多对多)
heipacker
博客等级 码龄17年 9粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值