文档章节

java基础——2final不简单

朱柳瑞
 朱柳瑞
发布于 2014/02/03 08:59
字数 886
阅读 182
收藏 8
        final——一个并不陌生的java关键字,修饰变变量(包括实例变量,类变量)、方法、类。下面一行很常用到的code:
public static final String BACE_INFO = "baseinfo";
        首先,先明确一下,
  1. final修饰的变量不可以重新赋值。
  2. final修饰的方法不可以被重写。
  3. final修饰的类不可以派生子类。
  4. final修饰的实例变量必须显式的指定初始值,并且只能在以下三个位置初始化。
public class FinalInstanceTest{
    //定义变量时初始化
    final int var1 = 2;
    final String var2;
    final double var3;

    //非静态初始化代码块
    {
        var2 = "吃饭睡觉打豆豆";
    }

    //构造器中初始化
    public FinalInstanceTest(){
        this.var3 = 3.14;
    }
}

但是本质上final实例变量的初始化都是在构造器中进行的。
    5. final修饰的类变量也必须在定义时或静态初始化块中显式初始化,而本质上都是在静态初始化块中进行的。

       我们着重看以下final修饰的字符串,小伙伴们判断一下下面程序的输出结果

public static void main(String[] args) {
	String str1 = "javacode";
	String str2 = "java" + "code";
	System.out.println(str1 == str2);  ------------------A

	String str3 = "java";
	String str4 = "code";
	String str5 = str3 + str4;
	System.out.println(str1 == str5);  ------------------B
}



        先公布结果:A 处代码会输出true 而B处代码会输出false。
        先来研究下A处代码。有人会说明明是两个String对象怎么会输出true呢?java存在一个java字符串缓冲池,他会缓存所有使用过的字符串直接量。str1 = "javacode" 这里便会缓存javacode这个字符串对象,而str2 = "java" + "code";可以在编译时确定str2为"javacode"所以系统自动将str2指向字符串缓存的"javacode"。所以str1和 str2指向同一个字符串对象。而B处的代码,str5不能再编译时确定,系统就不会将str5指向缓存池中的"javacode",结果也就会输出false。
        那么什么是编译时确定呢?我理解为变量的赋值中不访问普通变量,不调用方法,只是基本的算术运算表达式或字符串连接运算,这样的变量能够被系统编译时确定。显然上述代码中str1、str2符合,而str5不符合。
如何将B处也输出true 呢?我们用到了final关键字。
        修改代码如下
public static void main(String[] args) {
	String str1 = "javacode";
	String str2 = "java" + "code";
	System.out.println(str1 == str2);  ------------------A

	final String str3 = "java";
	final String str4 = "code";
	String str5 = str3 + str4;
	System.out.println(str1 == str5);  ------------------B
}



        这时B处将输出true。
        事实上final修饰的变量已经成为一个直接替换量(这是我自己起的名字),当后续代码再次用到这个变量时,系统会自动将其替换成相应的值,因此 String str5 = str3 + str4;相当于 String str5 = "java"+"code";str5也就可以编译时确定了。此外相对于实例变量而言,在定义时赋初始值,非静态初始化块中,构造器中赋初始值都是一样的,都将在构造器中执行,但是对于final变量只有在定义时赋初始值才会被直接替换。
        另外关于final修饰的方法,主要强调在继承中存在的问题。被final修饰的方法子类不能重写,而且实际上子类也无法访问到父类中final修饰的方法。


© 著作权归作者所有

共有 人打赏支持
朱柳瑞

朱柳瑞

粉丝 7
博文 6
码字总数 4127
作品 0
东城
程序员
《成神之路-基础篇》JVM——JVM参数及调优(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 JVM参数及调优 JVM实用参数系列 成为Java GC专家(5)...

05/05
0
0
java基础io流——配角也风流(不求甚解)

本章简单介绍几个常见的io流派生。 1:数据操作流(操作基本类型数据的流)(理解) 代码示例: 2:内存操作流(理解) 用于处理临时存储信息的,程序结束,数据就从内存中消失。 代码示例: 注:查看...

潇潇漓燃
05/30
0
0
《成神之路-基础篇》JVM——JVM内存结构(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是《成神之路系列文章》的第一篇,主要是关于JVM的一些介绍。 持续更新中 参考文章: Java虚拟机的内存组成以及堆内存介绍 Java堆和栈...

05/05
0
0
《成神之路-基础篇》JVM——垃圾回收(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收 ...

05/05
0
0
native关键字初识--java调用非java代码的接口

Java基础知识——JNI入门介绍(上) Java™ 本机接口(Java Native Interface,JNI)是一个标准的 Java API,它支持将 Java 代码与使用其他编程语言编写的代码相集成。如果您希望利用已有的代...

成长中的菜鸟
2015/02/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

【七】组合Action

本章描述了常用定义Action的方法。 自定义action builders 我们在action一章已经看过如何声明一个action——有request parameter、无request parameter、有body parser等等。你可以在 asynch...

Landas
30分钟前
0
0
Spring Boot实战之基础回顾

本文作者: 吴伟祥 本文链接: https://wuweixiang.cn/2018/08/21/Spring-Boot实战之基础回顾/ 版权声明: 本博客所有文章除特别声明外均为原创,采用CC BY-NC-SA 4.0 许可协议。转载请在文章开...

吴伟祥
30分钟前
0
0
OAuth认证开发

提示: 以下测试是基于项目安装成功,初始化数据库(initial_db.ddl, oauth.ddl, initial_data.ddl)后的测试, 也可在页面上点击"client_details"菜单里进行测试 方式1:基于浏览器 (grant_type=...

舒文joven
38分钟前
1
0
第二章-对象及变量的并发访问-第二篇

锁对象的改变 请阅读如下代码 public class MainClass { private String lock = "123"; public void printStringB() { try { synchronized (lock) { ......

简心
42分钟前
0
0
日志中记录代理IP以及真实客户端、apache只记录指定URI的日志

apache 日志中记录代理IP以及真实客户端 默认情况下log日志格式为: LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined 其中%h 是记录访问者的IP,如果在web的前...

李超小牛子
51分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部