Pages

搜尋此網誌

2013年12月24日 星期二

java OCP 題目解析:關於 java 指標的運作觀念

java OCP 題目解析:關於 java 指標的運作觀念

最近在看 OCP java 證照的題目,有個觀念與大家分享,在實際開發上才不會因為觀念不清楚產生 bug 時死的不明不白,題目如下:

資料來源:來喝杯JAVA咖啡

Given:

    class Foo {
        private int x;

        public Foo(int x) {
            this.x = x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getX() {
            return x;
        }
    }

    public class Gamma {
        static Foo fooBar(Foo foo) {
            foo = new Foo(100);
            return foo;
        }

        public static void main(String[] args) {
            Foo foo = new Foo(300);
            System.out.print(foo.getX() + "-");

            Foo fooFoo = fooBar(foo);
            System.out.print(foo.getX() + "-");
            System.out.print(fooFoo.getX() + "-");

            foo = fooBar(fooFoo);
            System.out.print(foo.getX() + "-");
            System.out.print(fooFoo.getX());
        }
    }

What is the output?

A. 300-100-100-100-100
B. 300-300-100-100-100
C. 300-300-300-100-100
D. 300-300-300-300-100

答案:

B

解析:

做這題頭腦不夠清楚可能會被搞混喔
這題是考JAVA 隱藏的指標觀念,其實規則很容易:
1. 方法的呼叫永遠都是傳值,方法在接到值之後,會另外產生一個空間來存這個值,也就是有兩份值,兩個位址
2. 等號的運算有分為基本資料型態(int, float等等) 和物件兩種
    2.1. 等號處理基本資料型態時是傳值
    2.2. 等號處理物件時是傳位址

依照題目的情況來模擬一下:

    Foo foo = new Foo(300);
    Foo fooFoo = fooBar(foo);

生成一個物件,並且呼叫下面方法,在呼叫之前,記憶體的情況如下

指標 main:foo
內容 Foo物件:X=300
        static Foo fooBar(Foo foo) {
            foo = new Foo(100);
            return foo;
        }

方法第一行接收了物件之後就另外產生空間複製一份,記憶體如下

指標 main:foo fooBar:foo
內容 Foo物件:X=300 Foo物件:X=300

方法第二行new 了一個物件,也就是生成了新的位址,把這個物件位指指派給foo,記憶體如下

指標 main:foo fooBar:foo
內容 Foo物件:X=300 Foo物件:X=300 Foo物件:X=100

你會發現,有一個空間沒有指標指到它了,沒錯,這樣一來這個空間隨時會被空間回收程序收走

方法第三行回傳了fooBar: foo指標

後來在主方法執行了這一行

foo = fooBar(fooFoo);

之後記憶體狀況會變成

指標 fooBar:foo
內容 Foo物件:X=300 Foo物件:X=300 Foo物件:X=100

只要記住前述兩大規則,就可以掌握所有JAVA 中所有的指標規則

我只有將排版美化,其他都是原作者的內容,另外還有一題特殊情形:

Given:

    public class KungFu {
        public static void main(String[] args) {
            Integer x = 400;
            Integer y = x;
            x++;
            StringBuilder sb1 = new StringBuilder("123");
            StringBuilder sb2 = sb1;
            sb1.append("5");
            System.out.println((x == y) + " " + (sb1 == sb2));
        }
    }

What is the result?

A. true true
B. false true
C. true false
D. false false
E. Compilation fails.
F. An exception is thrown at runtime.

答案:

B

解析:

Integer是int的WapperClass,雖然以物件的形式來表現,不過在做等於運算的時候要視為基本資料型態,以傳值的作法來做

一般物件的話當然做等於運算就是傳指標了

張貼留言