概述

final在英文中是最终的,不可更改的。在Java中final修饰变量,函数和类,就像这个单词的意思,一旦使用赋值之后不可更改。

final修饰的变量不可以被改变

finalTest类

public class finalTest
{
private String test = "test";
//final修饰的成员变量 第一种赋值方式
private final int a = 6; private final int b; private final int c; //final修饰的静态成员变量 第一种赋值方式
private final static int e = 6; private final static int f; public finalTest()
{
//final修饰的成员变量 第二种赋值方式
b = 5;
} {
//final修饰的成员变量 第三种赋值方式
c = 5;
} static
{
//final修饰的静态成员变量 第二种赋值方式
f = 6;
} public void test(final int g)
{
//final 修饰的局部变量第一种方式
final int d = 10; //final 修饰的局部变量第二种赋值方式
final int h;
h = 11; //调用此函数的已经进行赋值,再次赋值会报错
//g = 66;
}
@Override
public String toString()
{
return test;
} public static void main(String[] args)
{
final finalTest finalTest = new finalTest();
//final修饰,无法被改变
//finalTest = null;
System.out.println(finalTest);
finalTest.test = "test2";
System.out.println(finalTest);
}
}

输出

test
test2

final修饰基本数据类型,不能对基本数据类型重新赋值,基本数据类型变量不能被改变。但final修饰引用类型变量,不变的仅仅是他的一个引用,只要引用地址不变,他里面的成员变量是可变的。

final修饰的函数不可以被重写

finalTest类

public class finalTest
{
public final void test()
{
System.out.println("父类");
}
} class finalTestChild extends finalTest
{
// @Override
// public void test()
// {
//
// }
//final修饰的函数可以被重载
public void test(int a)
{
System.out.println("重载");
}
}

父类被final修饰的函数是无法被子类重写的,但final修饰的函数可以被重载。

final修饰的类不可以被继承

最典型是的例子是Java的String类,打开String类发现String类是被final所修饰。

finalTest类

继承一个被final修饰的父类,就会报错。很明显Java设计人员不希望我们对String类进行修改,个人理解是因为String类过于强大,Java的设计人员出于安全考虑,不希望它有子类。 因为这样可能危及到系统安全。所以final类中所有的类都隐式指定为是final的,无法覆盖他们,我们只能使用他规定的函数。所以当我们希望自己的类不被人继承时,就可以指定为final。

final的作用

  1. 效率,JVM和Java都会缓存final变量并对函数,和类进行优化。
  2. 设计和安全,上"锁",不希望自己的类和函数被人随意改变。

final的安全发布

创建一个对象,大致可以分为三个步骤

  1. 分配内存空间
  2. 将引用指向分配的内存空间
  3. 调用构造函数来初始化对象

这三个步骤不是原子的,执行到第二部,没进行初始化,此时如果这个对象能被当前范围之外的代码所使用,因为这时对象已经不是null了,被其他代码访问,会得到一个错误的结果。这就是不安全的发布。所谓安全发布,简单理解就是对象的创建能够保障在被别人使用前,完成数据的构造设置,或者说一个对象使用时,已经进行初始化。但是Java对此并没有进行保障,需要自己进行保障设置,如锁机制等。

对于final,当创建一个对象时,使用final关键字能够使得另一个线程不会访问到处于"部分创建"的对象。

  1. 当构造函数退出时,final字段的值保证对访问构造对象的其他线程是可见的。
  2. 一旦对象引用对其他线程可见,则其final成员也必须正确赋值。

所以借助final,就如同是你对对象的创建访问加锁了一样,天然保障了对象的安全发布

总结

许多并发错误都是没理解共享对象的既定规则,当发布一个对象时,必须明确说明对象的访问方式。

你真的知道final关键字吗?的更多相关文章

  1. 浅析Java中的final关键字(转载)

    自http://www.cnblogs.com/dolphin0520/p/3736238.html转载 一.final关键字的基本用法 在Java中,final关键字可以用来修饰类.方法和变量(包括 ...

  2. 浅析Java中的final关键字

    浅析Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...

  3. 浅析final 关键字

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法.下 ...

  4. 面向对象编程(十二)——final关键字

    final关键字 Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量. 在Java中,final关键字可以用来修饰类.方法和变量(包括成员变量和 ...

  5. [转载]浅析Java中的final关键字

    浅析Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...

  6. 转载:浅析Java中的final关键字

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法.下 ...

  7. java中的final关键字

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法.下 ...

  8. Java中关于final关键字

    final关键字,大学时一直没有理解,伴随到工作,郁闷......也可能大学真的没认真去学习 首先,final给人一看英语单词 不就是最终的嘛,最终的什么的呢 ? 小张现在就带大家 学习下..... ...

  9. 浅析Java中的final关键字(转)

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法.下 ...

随机推荐

  1. 网易面经(Java开发岗)

    网易面经(Java岗) 网易两面面经整理 岗位:我投递的是杭研所的Java开发岗位.行程:半天的时间南京=杭州之间穿行,单程2个小时,从杭州东站=网易大厦,单程1个小时(如果能买到城站高铁动车票可以从 ...

  2. Java EE的未来

    http://www.infoq.com/cn/articles/enterprise-Java-opinion 作为InfoQ下一年编辑关注点审核工作的一部分,我们挑选了Java作为深入探讨的主题. ...

  3. goquery 添加header 发起请求

    goquery 添加header 发起请求 我们知道使用net/http 很容易发起GET or POST 请求:并且在发起http请求时候,可以很容易的对header进行干预 例如: client ...

  4. Scala编程入门---数组操作之数组转换

    使用yield和函数式编程转换数组 //对Array进行转换,获取的还是Aarry val a = Array(1,2,3,4,5) val a2 = for(ele <- a) yield e ...

  5. java线程之线程同步

    本篇由于涉及多线程操作,所以线程是使用实现Runnable接口来创建的. 在上篇所示线程任务中,我们不难发现,是存在三步操作的: 第一:打印语句: 第二:计算sum=sum-1: 第三:线程休眠. 那 ...

  6. Pescal Triangle Two

    Description: Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3 ...

  7. netcore入门-基础

    .NETCORE1.0出来了,咦不错,什么开源,跨平台的,观望下等2.0:我擦2.0出来了可以学习了,截止到目前2.1都快出来了,是时候学习一下了. 先建一个webapi项目,从简单的demo开始 l ...

  8. (二)SpringBoot基础篇- 静态资源的访问及Thymeleaf模板引擎的使用

    一.描述 在应用系统开发的过程中,不可避免的需要使用静态资源(浏览器看的懂,他可以有变量,例:HTML页面,css样式文件,文本,属性文件,图片等): 并且SpringBoot内置了Thymeleaf ...

  9. springboot集成rabbitmq(实战)

    RabbitMQ简介RabbitMQ使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现(AMQP的主要特征是面向消息.队列.路由.可靠性.安全).支持多种客户端,如:Python.Ru ...

  10. String的split()方法可以将字符串按照特定的分隔符拆分成字符串数组

    在java.lang包中有String.split()方法,返回是一个数组------不管按照什么拆,拆出来是一个数组 String str = "1,2,3,4,5,6"; St ...