java学习(4)—— final关键字

final

final变量

final变量有成员变量和非成员变量(方法内的局部变量),在类成员中final经常和static一起使用,作为类常量使用。其中类常量必须在声明时候立即初始化final成员变量可以在构造函数初始化。

public class main{
	public static final int i ;
	报错,必须初始化,因为常量在常量池中就存在了,调用时不需要类的初始化,
	所以必须在声明时初始化。
	public static final int j;
	Main(){
	i=2;
	j=3}
	}
  • 对于类常量,JVM会在常量池中缓存,在读取该变量的时候不会加载这个类。
    (对于上面也就是说类是否初始化不影响这个常量池中的常量
public class Main {
	public static final int i = 2;
	Main(){
		System.out.println("调用构造函数")^该方法不会被调用
	}
	public static void main(String 【】args){
	System.out.println(Main.i);
}

@final修饰基本数据类型变量和引用

@Test
public void final修饰基本类型变量和引用(){
	final int a = 1final int【】 b ={1}final int【】 c ={1}//b=c;报错
	b【0=1final String aa ="a"final Fi f = new Fi();
	//aa = "b";报错
	//f = null 报错
	f.a =1;
}

@有关null的描述

final方法不能够被子类的方法重写,将方法声明为final,在编译的时候就已经静态绑定了,不需要在运行时动态绑定。final方法调用时使用的是invokespecial指令。
(静态和动态绑定将在继承中学习)

final类

final类不能被继承,其中的方法也都会是final类型的,java中的String类和Integer类都是final类型的

class Si{
//一般情况下final修饰的变量一定要被初始化。
//只有下面这种除外,要求变量必须在构造方法中被初始化。
//并且不允许有空参数的构造方法
//这样就能让每个实例都有一个不同的变量,并且此变量在每个实例中只会被初始化一次
//于是这个变量在单个实例中就是常量了
final int s;
Si (int s){
	this.s = s;
	}
}
class Bi{
	final int a = 1;
	final void go(){
	//final修饰方法无法被继承
	}
}
class Ci extends Bi{
final int a =1;
final void go(){
	//final修饰方法无法被继承
	}
}
class Ci extends Bi{
final int a = 1// 		void go(){
//       final修饰方法无法被继承
//}
}
final char[]a = {'a'};
final int[]b = {1};

final关键字的知识点

  1. final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会编译错误。final
    变量一旦被初始化之后不能再次赋值。

  2. 本地变量必须在声明的时候赋值。因为没有初始化的过程

  3. 在匿名类中的所有变量都必须是final变量。

  4. final方法不能被重写,final类不能被继承

  5. 接口中声明的所有变量本身是final的。类似于匿名类

  6. final和abstract这两个关键字是反相关的,final的就不可能是abstract(抽象)的
    (一个要求抽象,一个要求实现)

  7. final方法在编译阶段绑定,称为静态绑定(static binding)

  8. 将类,方法,变量声明为final能够提高性能,这样JVM就有机会进行统计,然后优化。

final方法

前面介绍过。。
好处

  1. 提高了性能,JVM在常量池中会缓存final变量
  2. final变量在多线程中并发安全,无需额外的同步开销
  3. final的方法是静态编译的,提高了调用速度
  4. final类创建的对象是只可读的,在多线程可以安全共享

实际操作

final用法

  1. 对于常量来说,意味着值永远不能改变,例如final int i = 100。
    (这里i的值永远都是100。)但是对变量来说又不一样,只能是标识这个引用不能被改
    变,例如final File f = new File(“c:\test.txt”);
    那么这个f是一定不能被修改的,但如果f本身有方法修改其中的成员变量,例如是否可读,
    是允许修改的——实际上是这个变量绑定了常量池里的常量,绑定关系不可变,但是有
    可能对常量本身进行修改。

【【【【【拓展部分】】】】】
@@关于空白final
final修饰的变量有三种:静态变量、动态变量、实例变量和局部变量,分别表示三种类型的常量。另外,final变量定义的时候,可以先声明,不赋初始值,这其中的变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以体现依据对象而有所不同,却有着保持其恒定不变的特征。

public class FinalTest{
final int p;
final int q = 3;
FinalTest(){
p=1;
}
FinalTest(int i){
p=i;//可以赋值,相当于重新定义p
q=i;//不能为一个final变量重复赋值
}

@@final内存分配
调用一个函数,除了函数本身执行的时间复杂度外,还有寻找这个函数所需的额外时间
(类内部有一个函数签名和其地址的映射表)。
所以减少函数调用次数就等于降低了性能消耗。

final修饰的函数会被编译器优化,优化的结果是减少了函数调用的次数。实现方式看下例:

public class Test {
final void func(){System.out.println("g");};
public void main(String[]args){
	for(int j=0;j<1000;j++)
	func();
}}
经过编译器优化以后,这个类就变成相当于这样:
public class Test{
final void func(){System.out.println("g");};
public void main(s=String []args){
for (int j=0;j<1000;j++)
{System.out.println("g");}
}}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值