從C轉Java過來,一些基礎理論不是太扎實,在使用final局部變量時出現了理解錯誤,今天驗證了一下,記下筆記。
- public class Main {
-
- public void finalTestFunc() {
- final FinalTest t = new FinalTest();
- System.out.println("T:" + t.toString());
- }
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- Main m = new Main();
- m.finalTestFunc();
- m.finalTestFunc();
- }
-
- }
FinalTest是個空類,啥都沒有,toString會轉換成其地址打印出來,上面一段程序的打印:
- T:FinalTest@c17164
- T:FinalTest@1fb8ee3
可以看到在finalTestFunc()函數中雖然t用final修飾了,但是兩次調用,每次都創建了新的對象,final只是標記了t在本次調用中不能再次指向別的對象,並不代表這個對象始終存在,整個程序生命周期中只初始化一次。
為什麼會有只初始化一次的錯誤理解呢?
其實剛開始使用Java的時候,理解是正確的,認為每次都初始化。
但是後來使用內部類,內部類如果訪問外部類的變量,這個變量就要加final修飾,因為對Java掌握不到位,此時錯誤的認為final將變量的生命周期改為了整個程序生命周期,而實際上此處加final是保證變量值一致性。
同樣在C++中的const也是這個現象,const局部變量的生命周期仍然是局部的,只有加上static才是全局的。
- #include <iostream>
- using namespace std;
-
- class A {
- private:
- int v;
-
- public:
- A() {
- v = 0;
- }
-
- void out() const {
- cout << "A=" << this << endl;
- }
- };
-
- class B {
- public:
- B() {
- }
-
- void constTest() {
- const A* a = new A();
- a->out();
- }
- };
-
- int main(int,char**) {
- B* b = new B();
- b->constTest();
- b->constTest();
- }
這段程序輸出:
- A=0x89a8018
- A=0x89a8028
即每次函數調用都創建了新的對象,只有加上在const後加上static,才是只初始化一次。