一:类成员
访问类成员变量时,不看调用者,因为最终在底层实现时都是转化成通过该类来调用
同一类的所有对象访问类成员时,可以看到是同一个类的所有实例对象共享同一块内存区 所有实例对象共享同一块内存区
因此,即使某个实例为null,也可以访问类成员变量
二:final
1、final修饰的成员变量,一旦有了初始值,不能再进行复制
换句话说,只要是final修饰的,相当于常量,只能显示初始化一次,在初始化块、声明时、构造器内,只可以进行一次显示的初始化。再次进行初始化时会报错。
2、不能再final修饰的变量初始化之前访问final修饰的成员变量
初始化之前虽然不能直接访问,但是可以通过方法来访问, 问题就来了,还没有初始化,就可以访问,
所以:建议、final修饰的变量,在没有初始化之前,任何地方都不要调用该变量。
3、在java语言中,成员变量可以不用初始化,系统会有默认的初始值。
局部变量不可以,局部变量必须由开发人员进行显示的初始化,JVM不会默认初始化
4、final修饰的基本变量,相当于常量,只能初始化一次,不能在进行改变初始化
final修饰的引用变量,是将引用变量指向了某个对象地址,此时,该引用变量指向的对象不能再进行改变,但是该对象本身可以变化
如,Person p = new Person(); p指向的是Person对象的地址,不能再改变
p.setName("123"); Person对象可以改变本身,只要p还是指向Person就可以
5、宏替换
final修饰的变量满足一下三个条件,就不再是一个变量,而是一个直接量;
1)final修饰
2)声明时有初始化
3)初始值编译期就可以定下来
对应实例变量,初始化可在非静态初始化块、声明时、构造器内进行初始化,三个位置初始化效果基本一样
但是final修饰的实例变量 ,如果想有宏变量的效果,只能是在定义时进行声明时初始化才可以
当满足上面三个条件是,就是宏变量,遇到此类变量的运算,JVM会直接进行宏替换,引用该变量的地方直接替换为该变量的值
final String b = "3" + String.valueOf(4);
final String c = "3" + "4";
sop("34" == c); true 编译时c就已经确定
sop("34" == b); false 调用了方法,编译时无法确定b值
String a = "abc";
String b = "ABC";
String c = "abc" + "ABC";
sop("abcABC" == c) true
sop("abcABC" == a + b) false; 编译期无法确定a b值
如果想让sop("abcABC" == a + b)为true也可以,只要让其编译期值能确定就可以进行宏替换
如下,final修饰,可直接进行宏替换。
final String a = "abc";
final String b = "ABC";
6、final修饰方法不可重写,
final修饰类不可派生子类
7:、理解可变类和不可变类