java修饰符final

final修饰符

1.final修饰变量

final修饰的变量指向是不可变的,比如string类型的数据,初始化就不可以改变了

例如:

public class FinalTest{
	public static void main(String[] args) {
		final String a = "str1";
		a = "str2";
	}
}

因为final修饰字符串所以a字符串是不可变的,所以上面代码编译是会报错的,原因是当a改变成str2的时候,引用变量指向会发生改变,注意为什么会在编译时候就会报错,因为JVM分配内存的时候将final视为不可变常量,既然是不可变常量,所以就会出现编译是报错,而不是运行时报错

在分析一段代码:

public class FinalTest{
	public static void main(String[] args) {
		final String a = aaa();
		final String b = "str";
		String a1 = a +"2";
		String a2 = a +"2";
		String b1 = b +"2";
		String b2 = b +"2";
		System.out.println(b1 == b2);//结果true
		System.out.println(a1 == a2);//结果false
	}
	
	static String aaa(){
		return "str";
	}
}
此时a,b同为final而且都是str为什么一个结果是true,一个是false,因为a并不是编译时就确定的变量,而是编译之后就确定的常量,而b编译时就确定常量,b1b2 string的生成是由两个常量生成的,所以引用变量指向一定是一样的 (相当于a1="str"+"2",a2="str"+"2"),而a1a2是由运行时常量生成所以两个地址是不一样的。但是如果将常量b的final去掉,那它的结果将会变成false,因为不是编译时就确定的 常量,所以他们他的指向就不一样。

如果修饰对象:

public class FinalTest{
	public static void main(String[] args) {
		final StringBuffer buffer = new StringBuffer("str");
		buffer.append("a");
                //buffer = new StringBuffer("str");//这句会报错
       }
}
这段代码是正确的,虽然进行了值的修改,但是他的引用变量指向没有发生改变,因为buffer是一个 对象,只要对象指向没有发生改变就不会有错误,

如果在后面加上语句buffer = new StringBuffer("str");就会报错,这样会改便buffer的指向

2.final修饰方法

这个没有特别好讲的,就是被final修饰的方法不能被子类重写。如果你想设定一个方法不能被子类继承就加上一个final。使用final就是为了不让子类继承。

注意:类的private方法会隐式地被指定为final方法。

3.final修饰的类

被final修饰的类不能被继承

public class FinalTest extends Test{
	public static void main(String[] args) {
		
	}
}

final class Test{
	
}
编译时候就会报错,Test类是不能继承的。

4.final使用在方法内部类

public class FinalTest {
	public static void main(String[] args) {
		
	}
	
	static void aaa(){
		final int x = 1;//这里必须时final
		class bbb{
                       void display(){
				System.out.println(x);
			}
		}
	}
}
x变量必须声明成final,当内部类使用方法中的变量x的时候会有一个 复制品产生,就是说会有一个private int x = 1;的变量在bbb内部类中,这样就会出现一定得问题, 问题就是局部变量的生命周期与局部内部类的生命周期的不一致性,也就是说,bbb类要使用x变量,如果aaa()方法调用结束,x可能被视为没有的数据就会被回收掉,一旦被回收掉,方法内部类不一定会被销毁,可能被其他引用没有被立刻销毁,又需要使用x,这时候就是出现内部类要访问一个不存在的局部变量。如果 不是final,就不能在内部类种使用,就无法保证复制品与原始变量保持一致了。因为,在方法中改的是原始变量,而局部内部类中改的是复制品。其实这些做法的根本原因都是为了维护复制品与原始变量的一致性


总结来说,方法内部类使用final就是为了实现一致性。





  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值