1,final是拿来定义一个成员是否可变,可以拿来修饰类,变量,方法。表示不可改变。final的分析要结合初始化。
2,final修饰成员变量的时候,必须显示的为这些成员变量赋初始值,否则无意义。
3,final修饰局部变量的时候,可以在定义的时候指定默认值,也可以在后面代码里面赋初始值。但是只可以赋值一次。
2,3,这里结合分析,由于成员变量是在编译的时候完成初始化的,因此必须显示指定。而对于局部变量则不要求。
4,final修饰基本类型的变量的时候,直接是变量值不可以改变,但是修饰引用类型的时候,变量里面存放的实际是指向对象的地址,也就是说 引用指向的对象不可以改变但是对象里面的内容还是自由改变的。
5,final与宏。用final修饰在定义的时候必须指定初始值,使得在编译的时候初始值被确定下来(注意尤其是成员变量的时候即使是在初始化可 或者构造函数指定初始值也不是宏)。否则只是普通的final变量。
6,宏跟常量池有相似之处,如下:
final String book1 = “今天是晴天” + 99.0;
final String book2 = “今天是晴天” + String。valueOf(99.0);
看上去book1与book2是相等的,实际上在代码里是不相等的 。book1在编译的时候已经定下,指向一个字符串对象。而book2由于valueOf(99.0)需要调用String的方法,属于运行时内容,在编译的时候无法确定,所以book2只是一个普通的final变量而已,它会指向另一个字符串对象而不是book1指向的那个,所以实际上两个是不相等的。
在常量池中同理,如下:
String st1 = “开心”;
String st2 = “快乐”;
String item1 = “开心” + “快乐”;
String item2 = st1 + st2;
String item3 = “开心快乐”
item1 == item2? 这里是不成立的,同理,item1在编译的时候指向常量池里面的某个对象,而item2由于st1与st2在编译的时候无法替换成字符串,所以属于运行时的动作,因此item2是在运行时确定下来的,指向另外一个非item1的变量。如果这里st1与st2用final来修饰,那么就是宏,就可以进行转换,此时item2 == item1成立。
item1 == item3?这里是是成立的,常量池在编译的时候缓存字符串,item2指向的是item1所指向的对象。
7,final方法不可以被重写,但是重载是完全没问题的。
当final修饰的方法是private的时候,子类并没有继承该方法,那么此时如果子类里面有个方法跟该方法同名同参数是没有问题的,因为 是属于子类定义的新方法而不是重写。
8,final类,final类不可以有子类。
9,不可变类(还没看。。。)