目前各種語言中向函數傳遞參數的類型分爲三種:java
其中按值傳遞表示方法(函數)接收的是調用者提供的變量的拷貝,不改變參數的值;按引用傳遞表示方法(函數)接收的調用者提供的變量地址;按指針傳遞表示方法(函數)接收的是調用者提供的指針的拷貝,不改變指針的值和地址,但能夠改變指針所指向的地址。數組
java中沒有指針和引用傳遞,只有值傳遞,所以,在函數中改變局部變量的參數不會影響到全局變量的值。函數
此時,雖然局部變量str1和str2與全局變量的str1和str2同名,可是,局部變量獲得的僅僅是常量區值的地址的拷貝;若是交換局部變量的值,只是改變了局部變量的指向;不會影響大到全局變量。而方法區中的常量是final類型的,更是不會改變。spa
示例以下: String x = new String("x111");指針
String y = new String("y111"); swap(x,y); System.out.println(x); System.out.println(y); public static void swap(String a, String b) { String temp = a; a = b; b = temp; }
int[] arr = new int[3];
change(arr);
System.out.println(arr.length);
public static void change(int[] arr) {
arr = Arrays.copyOf(arr, arr.length * 2);
}code
輸出的結果是:x111,y111,3blog
有人可能會說,String是一個final類型的類,太過特殊,那咱們使用包裝類試試。示例以下,獲得的結果仍然是:3,4get
Integer inteA = new Integer("3"); Integer inteB = new Integer("4"); swapInte(inteA, inteB); System.out.println(inteA); System.out.println(inteB); public static void swapInte(Integer InteA, Integer InteB) { Integer temp = 0; temp = InteA.intValue(); InteB = InteA; InteA = temp; }
因而可知,不論java向方法中傳遞的是基本類型的數據仍是引用類型的數據,其實質都是將該變量指向的地址拷貝一份傳給了局部變量,本質上拷貝的該變量指向的一個值,隨便局部變量如何玩耍,都不會波及全局變量。string
爲了對比說明值傳遞與指針傳遞、引用傳遞的區別,下面結合C指針傳遞和C#的引用傳遞說明下;it
指針傳遞和引用傳遞的本質是將全局變量自身的地址傳給了局部變量,所以,局部量修改時,同時也修改了全局變量的地址。
C語言的指針交換示例:
#include <stdio.h> void swop(char **str1, char **str2) { char *temp = NULL; temp = *str1; *str1 = *str2; *str2 = temp; } int main() { char *str1 = "hello"; char *str2 = "world"; printf("str1 = %s, str2 = %s\n", str1, str2); swop(&str1, &str2); printf("str1 = %s, str2 = %s\n", str1, str2); return 0; }
C#的引用傳遞
static void Main(string[] args) { string x = "hello"; string y = "world"; Console.WriteLine("x={0},y={1}",x, y); Swap(ref x, ref y); Console.WriteLine("x={0},y={1}", x, y); Console.ReadKey(); } static void Swap(ref int x, ref int y) { int temp = x; x = y; y = x; } static void Swap(ref string x, ref string y) { string temp = x; x = y; y = x; }
那麼,咱們如何作到修改函數局部變量的同時也修改全局變量呢?
方式1:使用數組,此時修改的是全局變量和局部變量共同指向的地址中的值,所以,兩者的值都會改變。
int[] arr = {3,4}; System.out.println(arr[0]); System.out.println(arr[1]); arr = swap(arr); System.out.println(arr[0]); System.out.println(arr[1]); public static int[] swap(int[] arr){ int temp = arr[0]; arr[0] = arr[1]; arr[1] = temp; return arr; }
方式2:使用反射
Integer inteA = new Integer("3"); Integer inteB = new Integer("4"); try { swap(inteA, inteB); } catch (Exception e) { e.printStackTrace(); } System.out.println(inteA); System.out.println(inteB); public static void swap(Integer a1, Integer b1) throws Exception { Field value = Integer.class.getDeclaredField("value"); value.setAccessible(true); int temp = a1.intValue(); value.set(a1, b1.intValue()); value.set(b1, temp); }
方式3:使用類封裝的屬性進行交換,這個方式網上例子不少,在此再也不舉例說明了。
總結:Java中方法的參數傳遞都是值傳遞,方法內局部變量的改變不會影響到全局變量。可是對局部變量和全局變量共同指向的值進行了修改的話,全局變量和局部變量的值都會改變。