您的位置:首页 > 编程语言 > Java开发

Java Final修饰符存储位置以及作用意义

2017-04-01 11:59 281 查看

前言 

      相信大家在开发中,对于final修饰符都比较常见,它会将修饰的变量固定不可重复赋值。但是我们是否思考过被它所修饰属性变量或类存储在哪里呢?下面已我将用比较有趣的问答形式,让大家对final有一个全面的认识。在不了解java的内存分配存储知识的可以先异步看一下内存如何分配(简单普及知识)

问题一

究竟final修饰的数据被存储在什么位置呢?

答:
我们要知道数据存储在哪些内存的不同区域,主要分别是:

堆区heap(存储对象)
栈区stack(存储引用)
静态区static storage(存储静态的)
常量区constant storage(存储不变的)

被final修饰的变量会变成常量,所以是在常量区。而常量区又是位于堆区的,所以答案就自然明白了。

问题二

final修饰变量、方法、类有什么作用?

答:

1、当final修饰变量时,作用:

       无论属性是基本类型还是引用类型,“值”都是不能变的。 这个值,对于基本类型来说,变量里面放的就是实实在在的值,而对于引用类型来说,变量里面放的就是引用地址,所以当用final修饰引用类型变量时,其实指的是它里面的地址不能变,并不是说 这个地址所指向的对象或数组的内容不能变,这个一定要注意。

例如:类中有一个属性是final Person p=new Person("name"); 那么你不能对p进行重新赋值,是可以改变p里面属性的值,p.setName('newName');

2、当final修饰方法时,作用:

可以被继承,但继承后不能被重写。

3、当final修饰类时,作用:

类不可以被继承。

问题三

为什么匿名内部类和局部内部类只能访问final变量?

从Java设计的角度来说,单纯的保护数据安全和代码稳定。因为Java通过类的封装规范了类与类之间的访问权限,而内部类却打破了这种规范,它可以直接访问自身所在的外部类里私有成员,而且自身还可以创建相同的成员,从作用域角度看,内部类的新成员修改了什么值,外部方法也是不知道,因为程序的运行由外而内的,所以外部根本无法确定内部这时到底有没有这个东西。综上所述,选择final来修饰外部方法的成员,让其引用地址保持不变、值也不能被改变。

Final的意义

先看一个有趣现象:

byte  a = 1;
byte  b = 3;
byte  c = a+b; 		//直接加会出错,因为运算时Java虚拟机进行了转换,导致把一个int赋值给byte

-----------------------------------------------------------------------------------

final  byte  a = 1;
final  byte  b = 3;
byte c = a + b;		//加上final就不会出错。


再看段简单的代码:
  
public class Test1{ //外部类

public void test(final String message){ //外部类方法

class Test2{	//内部类

void print(){ //内部类方法
System.out.println(message);  //先看这里!!!
}
}
}
}
public static void main(String[] args){
Test1  cls = new Test1();
cls.test("打印字符串");
}
我们重点看message变量。先看内部类方法中的变量message,它即不是内部类的静态变量、也不是临时变量、更不是方法参数,它只是引用了外部类方法中的变量,所以它的引用地址只是在外部类方法中。如果此时将外部类方法中的message地址指向其他对象去引用的话,则内部类方法中的message就失去了引用,可能被回收,如果在回收后,异步线程再次去访问怎么办?

总结:

使用final修饰符不仅会保持对象的引用不会改变,而且还会保护这个对象在回调方法中的生命周期,所以这才是final修饰变量和final修饰参数的根本意义!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: