java入門(3)--函數

函數和方法

若是咱們常常要進行一些類似的處理過程,就能夠把這個處理過程封裝爲函數java

函數能夠被屢次重複調用,從而實現代碼重用和隔離的目的。數組

在面向對象的語言中,函數常常和對象綁定在一塊兒,爲區分起見,這時它被稱爲方法函數

由於java是徹底面向對象的,函數必須從屬於某個類。因此java中的函數都被稱爲方法。spa

若是方法前以 static 修飾,則稱爲靜態方法,能夠粗略地認爲,它與 c 語言的函數的概念大體相等了。設計

方法能夠在其括號中列出調用它時須要準備的參數,叫形式參數指針

方法也能夠有一個返回值(或沒有,此時寫void)。code

下面,咱們調用方法 f,求兩個整數的末位是否相同。對象

 1 public class A0403
 2 {
 3     static boolean f(int a, int b){
 4         int a1 = a % 10;
 5         int b1 = b % 10;
 6         return a1==b1;
 7     }
 8     
 9     public static void main(String[] args){
10         System.out.println(f(101,12));
11         System.out.println(f(65432,12));        
12     }
13 }

這個方法接受兩個參數,都是整數,它進行一系列的處理後,返回一個布爾值。blog

return 語句結束 f 方法的執行,並返回一個指定的值。編譯

在遇到 return 語句後,f 方法的其它代碼就再也不執行,而是要返回調用它的那個方法中。固然,在此方法中,return 語句後剛好沒有更多的語句了。

若是一個方法定義了返回值,它在結束執行以前就必定會遇到 return 語句,不然會引起編譯錯誤。

形參獨立原理

若是在被調函數中改變了形參的值,會不會影響調用的一方呢? 不會!

咱們看這個例子:

 1 public class A0404
 2 {
 3     static void f(int x){
 4         int sum = x % 10;
 5         x /= 10;
 6         sum = sum * 10 + x % 10;
 7         x /= 10;
 8         sum = sum * 10 + x % 10;
 9         System.out.println(sum);
10         System.out.println("x=" + x);
11     }
12     
13     public static void main(String[] args){
14         int a = 368;
15         f(a);
16         System.out.println("a=" + a);    
17     }
18 }

這裏的函數f的功能是:把傳給它的3位數 x 的數位反轉並輸出。

爲了觀察,咱們額外輸出了 a 的值,以及 x 的值。

經過結果能夠看到,雖然 x 的值在計算過程當中發生了變化,但這並不會影響 a 的值。

實際上,在調用 f 以前,要爲它準備須要的參數,這些參數必須新建立,因此才稱爲形式參數。

也就是說,在沒有調用 f 函數的時候,這些形參變量是不存在的,在屢次調用 f 的時候,這些形參就會被建立屢次。

建立形參後,把實參的值(這裏就是 a 的值)拷貝給它,而後纔開始 f 的執行。

當 f  執行結束後,形參變量會被自動釋放掉。

從更底層的機制看,這個形參的分配與釋放的過程是經過棧來完成的。

函數調用前,要把返回的位置,須要的參數等信息壓棧,在函數執行完畢後,自動彈棧,恢復執行前的樣子。

若是被調用的函數還會去調用其它函數,這個過程還會繼續上演。

這樣,棧可能就會越漲越高,但函數的執行總有結束的時候,那時棧就會落回來。

若是因爲某種設計失誤,致使函數調用一直沒能正確返回,而是不斷地調用其它的函數,就會致使棧的溢出,這是很常見的程序錯誤。

從參數傳遞的原理上咱們看到,實參與形參是各自獨立的變量,除了開始的時候,實參拷貝給形參外,它們再不會有任何聯繫。這叫作

"形參獨立原理"。

這種設計爲咱們省去了許多麻煩,但有時咱們可能會想讓被調方與主調方共享一個變量,而不是各自獨立,這怎麼辦呢?

答案是傳指針,在java中叫作:引用。

引用做爲參數

引用的本質是持有另外一個對象的地址。

若是對一個引用進行復制,只不過是兩個引用指向了同一個對象,並沒複製對象自己。

引用與面向對象的體系緊密聯繫在一塊兒,因此要等到學了初步的面向對象的知識後咱們才能更好地理解它。

但這裏,咱們能夠先看看數組的行爲,來窺其端倪。

數組就是一種對象類型,咱們定義的數組變量,其實是指向實際數組對象的指針,或說:引用。

 1 public class A0404
 2 {
 3     static void f(int[] x){
 4         for(int i=0; i<x.length; i++){
 5             if(x[i] < 0) x[i] = -x[i];
 6         }
 7     }
 8     
 9     public static void main(String[] args){
10         int[] a = {5, -3, 6, 10, 0, -15};
11         f(a);
12         System.out.println(java.util.Arrays.toString(a));
13     }
14 }

這裏的形參 x,實參 a 都不是數組自己,它們是指向數組的引用。

雖然  x 和 a 也是按照一樣的規則,不會相互影響,但因爲它們指向了同一個對象,這就引發了複雜的現象。

從結果上,咱們能夠觀察到,在 f 方法中修改了數組對象的值,在主調方打印數組時也看到了這些變化。

其原理圖:

引用是一種在主調函數和被調函數間共享數據的經常使用手段。

在上面的這個例子中,引用變量自己並無發生變化。發生變化的是引用所指向的對象,因此「形參獨立性原理」並無所以而破壞。

咱們可能會看到某些材料上寫着: java 有兩種傳遞參數的方式,一種是傳值(傳拷貝),另外一種是傳引用。

這可能會產生一些誤導。實際上Java只有一種傳遞參數的方式,就是傳值。

而這個被傳遞的值有可能會剛好是一個引用類型,就會引發一些相似共享變量的效果,其實並無什麼特殊的祕密,也不該該算是「另外一種」傳遞方式。

相關文章
相關標籤/搜索