A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 肖涵 中级黑马   /  2014-4-2 18:21  /  1002 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

一 概念
   在Java中, 可以使用final关键字修饰类、方法以及成员变量。

1 final标记的类不能被继承
   在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。

2 final标记的方法不能被子类重写
① 把方法锁定,防止任何继承类修改它的意义和实现
② 高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率

3 final标记的变量即成为常量,只能被赋值一次

二 用法

1 对于引用类型和值类型来说
  final的变量一旦被赋值,就不能再此改变。但对于引用类型,其“不可改变”的是指其地址不能改变而其属性可以改变。



2 对于成员变量和局部变量来说
对于final的成员变量,对其赋值有两种方式:① 声明时即赋值;②构造方法中赋值。
对于final的局部变量,对其赋值有两种方式:①声明时即赋值;②使用的时候赋值。

例子一
public class Test
{
final int a;
final int b = 0;//声明时赋值
public Test()
{
  a = 0;
  // b = 1;//编译不能通过
}
public Test(int i)
{
  a = 1;
}
public static void printFinal()
{
  final int m = 100;
  // m = 101;//编译不能通过
  final int n;
  n = 102;
  // n = 103;
  System.out.println("m + n=" + m + n);
}
}

例子二
import cn.xy.model.Person;
public class Test2
{
final Person p = new Person("xy");
final Person p2;
public Test2()
{
  p2 = new Person("xy");
  p.setName("xyy");
  // p = new Person("Jim");//编译不能通过
  // p = null;
}
public Test2(int i)
{
  p2 = new Person("xy");
}
public static void printFinal()
{
  final Person p = new Person("xy");
  p.setName("xyy");
  // p = new Person("Jim");
  // p = null;
}
}

3 关于final修饰类和方法的例子这里不举例,读者可以试一试。

三 final内存分配

   调用一个函数除了函数本身的执行时间之外,还需要时间去寻找这个函数(类内部有一个函数签名和函数地址的映射表)。故减少函数调用次数就等于降低了性能消耗。final修饰的函数会被编译器优化,优化的结果是减少了函数调用的次数。

public class Test3
{
final void function()
{
  System.out.println("xy");
}

public static void main(String[] args)
{
  Test3 t = new Test3();
  for(int i = 0;i< 1000;i++)
  {
   t.function();
  }
}
}

经过编译器优化之后,这个类变成了相当于这样写:
public class Test3
{
final void function()
{
  System.out.println("xy");
}

public static void main(String[] args)
{
  Test3 t = new Test3();
  for(int i = 0;i< 1000;i++)
  {
   System.out.println("xy");
  }
}
}
优点:
  编译器直接将function的函数体内嵌到了调用函数的地方,这样的结果是节省了1000次函数调用,当然编译器处理成字节码,只是我们可以想象成这样,看个明白。

缺点:
  当函数体若太长时用final会适得其反,因为经过编译器内嵌之后代码长度大大增加,于是就增加了jvm解释字节码的时间。而且如果final修饰的方法体过大的话,编译器可能会放弃内联。

评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

3 个回复

倒序浏览
谢谢楼主的分享!!!非常有用!!!
回复 使用道具 举报
谢谢  终于了解final的用法了
回复 使用道具 举报
总结的很好,学习了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马