深刻理解Java編程的7個例子

 深刻理解Java編程的7個例子   佟強 2009年11月7日 http://blog.csdn.net/microtong

 1. 閱讀下列代碼回答問題(第一個Java程序,理解PATH和CLASSPATH,學會使用javac和java命令)

 

  1. package cn.edu.uibe;  
  2. public class HelloWorld {  
  3.     public static void main(String[] args) {  
  4.         System.out.println("Hello World!");  
  5.     }  
  6. }  

 

問:

(1)上面代碼所在的源文件的文件名是_______________?
(2)在DOS提示符下,當前目錄爲該源文件所在的目錄,PATH環境變量已包含編譯程序所在的路徑,編譯目標路徑爲“D:/classes”,編譯命令行是_____________?
(3)爲了讓Java解釋器能夠找到編譯後的類文件,需要如何設置環境變量___________?
(4)在正確設置了相關的環境變量之後,運行HelloWorld類的命令行是____________?


答案:

(1)HelloWorld.java,公共類必須定義在和類名同名的文件中,文件名區分大小寫。

(2)javac -d D:/classes HelloWorld.java ,-d給出輸出目錄,javac會在D:/classes創建包的目錄層次結構cn/edu/uibe/HelloWorld.class

(3)set CLASSPATH=.;D:/classses,CLASSSPATH給出Java尋找.class文件的多個路徑,路徑之間用分號分隔,“.”表示當前路徑。

(4)java cn.edu.uibe.HelloWorld,注意需要給出包名,類名後面不要加“.class”。

2. 閱讀下列代碼回答問題(關於private的理解)

 

  1. public class Light {  
  2.     private int brightness = 5;  
  3.     public void brighten(Light another){  
  4.         another.brightness++;  
  5.     }  
  6.     public static void main(String[] args) {  
  7.         Light light1 = new Light();  
  8.         Light light2 = new Light();  
  9.         light1.brighten(light2);  
  10.     }  
  11. }  

 

問:上面代碼Java編譯器是否會給出錯誤提示?爲什麼?

答案:不會出現錯誤提示,private限制了私有變量只能被同一個類訪問,但是沒有限制同一個類的不同對象之間互相訪問私有變量。實際上,private是在編譯時進行檢查,如果想限制同類對象之間互相訪問,需要在動態運行時實現,開銷較大,而且沒有必要。

3. 閱讀下列代碼回答問題(關於多態性的理解)

 

  1. class Base {  
  2.     int i=1;  
  3.     void f(){  
  4.         System.out.println("Base.f()");  
  5.     }  
  6.     void g(){  
  7.     f(); //會調用上面的f()方法嗎?  
  8.     }  
  9. }  
  10. public class Derived extends Base { //繼承了Base類  
  11.     int i=2//Derived類的對象有1個i還是2個i呢? 答:2個  
  12.     void f(){ //覆蓋override了f()方法  
  13.         System.out.println("Derived.f()");  
  14.     }  
  15.     public static void main(String[] args) {  
  16.         Derived d = new Derived(); //創建子類對象  
  17.         Base b = d; //沒有創建對象,僅僅是父類引用指向了子類對象  
  18.         d.f(); //將會輸出Derived.f()  
  19.         b.f(); //也會輸出Derived.f(),方法具有多態性  
  20.         System.out.println(d.i); //輸出的是2,d.i訪問子類中定義的變量i  
  21.         System.out.println(b.i); //輸出的是1,b.i訪問的是父類中定義的變量i,成員變量是不會動態綁定而表現出多態性的。        
  22.         d.g(); //輸出Derived.f()  
  23.         b.g(); //也輸出Derived.f(),從父類中調用被覆蓋的方法f(),也將調用到子類中更具體的方法。  
  24.     }  
  25. }  

 

問: 寫出上面代碼的輸出?

答案:參見代碼註釋,子類和父類中定義同名的變量時,僅僅是隱藏了,變量沒有多態性;而對於覆蓋的方法,Java表現出多態性,

會調用更具體的子類裏面的方法,無論從哪裏調用,無論使用什麼引用類型調用。

4.閱讀下列代碼回答問題(關於匿名內部類的理解)

 

  1. interface A {  
  2.     void f();  
  3. }  
  4. public class B {  
  5.     public void f(A a) {  
  6.     }  
  7.     public static void main(String[] args) {  
  8.         B b= new B();  
  9.         b.f(new A() {  
  10.             public void f() {  
  11.             }  
  12.         });  
  13.     }  
  14. }  

 

問:請解釋語句
b.f(new A() {
    public void f() {
    }
});
的含義與作用。

答案:

   這個語句在參數表中定義了一個匿名內部類,這個匿名內部類實現了接口A,實例化了一個匿名內部類的對象,並將這個對象傳遞給了接收接口A作爲參數的方法f(A a)。需要注意的是接口A中的方法f()和類B中的方法f(A a)沒有任何關係,是不同的方法。


5. 閱讀下列代碼回答問題(關於static的理解)

 

  1. public class Static {  
  2.     static int i = 0;  
  3.     int j=0;  
  4.     public static void main(String[] args) {  
  5.         Static s1 = new Static();  
  6.         Static s2 = new Static();  
  7.         s1.i++;  
  8.         s2.i++;  
  9.         s1.j++;  
  10.         s2.j++;  
  11.         System.out.println(s1.i);  
  12.         System.out.println(s1.j);  
  13.         System.out.println(s2.i);  
  14.         System.out.println(s2.j);  
  15. }  
  16. }  

 

問:寫出上面代碼的輸出。

答案: 2 1 2 1,i是靜態變量,類的所有實例共享同一個i,通常我們不通過引用變量訪問靜態變量,而是通過類名訪問Static.i,注意Static是我們自己定義的類名,而小寫的static是關鍵字,表示靜態的,爲類的所有實例共享的變量或方法。j是實例變量,每個對象具有不同的,屬於其自身的一個變量j。

6. 閱讀下列代碼回答問題(關於引用變量的理解)

 

  1. class Counter{  
  2.     int i=0;  
  3. }  
  4. public class Reference {  
  5.     public void plus(int i){  
  6.         i++; //不會改變傳遞進來的參數的值,Java傳遞基本類型時進行了值的拷貝  
  7.     }  
  8.     public void plus(Counter c){  
  9.         c.i++; //會改變,因爲c是一個引用變量,相當於指針  
  10.     }  
  11.     public void create(Counter c){  
  12.         c = new Counter();   
  13.                   c.i++; //不會改變,因爲c執行了另外一個新建的對象  
  14.     }     
  15.     public static void main(String[] args) {  
  16.         int i = 0;  
  17.         Reference r = new Reference();  
  18.         Counter c1 = new Counter();  
  19.         Counter c2 = new Counter();       
  20.         r.plus(i);  
  21.         r.plus(c1);  
  22.         r.create(c2);         
  23.         System.out.println(i);  
  24.         System.out.println(c1.i);  
  25.         System.out.println(c2.i);  
  26.     }  
  27. }  

 

問:上面代碼輸出是?

答案:參考代碼註釋,輸出應該是:0 1 0

7. 閱讀下列代碼回答問題(關於異常的理解)

 

  1. class MyException extends Exception{  
  2.     public MyException(String message){  
  3.         super(message);  
  4.     }  
  5. }  
  6. public class ExceptionDemo{  
  7.     public void f(int num) throws MyException {  
  8.         if(num<0){  
  9.             throw new MyException("參數不能爲負數!");  
  10.         }  
  11.         System.out.println(num);  
  12.         }  
  13.     public void g(){  
  14.         try{  
  15.             f(1);  
  16.             f(3);  
  17.             f(0);  
  18.             f(-1);  
  19.             f(2);  
  20.             f(-5);  
  21.         }catch(MyException e){  
  22.             System.err.println(e.getMessage());  
  23.             return;//會立即返回嗎?答:不會!  
  24.         }finally{  
  25.            System.out.println("無論什麼時候!");     
  26.         }  
  27.     }  
  28.     public static void main(String[] args) {  
  29.         ExceptionDemo demo = new ExceptionDemo();  
  30.         demo.g();  
  31.     }  
  32. }  

 

問:上面代碼輸出是?

答案:輸出是:1 3 0 參數不能爲負數! 無論什麼時候!

try語句塊裏面的一行代碼拋出了異常,後續代碼就不再執行了,而是轉到catch開始匹配異常類型。finally語句塊裏面的代碼始終會被執行,即使在catch語句塊裏面有行return語句也不會立即返回,Java確保finally語句塊執行完函數纔會返回。

 

《Java程序設計課件》 http://sit.uibe.edu.cn/java

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章