你真的瞭解JAVA的形參和實參嗎?
「碼匠筆記」
前幾天在頭條上看到一道經典面試題,引發了一些思考。也是寫這篇文章的導火索。
背景
請看題:
publicclassMain{
publicstaticvoid main(String[] args){
Integer a =1;
Integer b =2;
System.out.println("a="+ a +",b="+ b);
swap(a, b);
System.out.println("a="+ a +",b="+ b);
}
privatestaticvoid swap(Integer numa,Integer numb){
//請實現
}
}
看到這個題後 瞬間覺得有坑。也覺得為什麼要書寫一個 swap
方法呢?如下實現不是更簡單:
publicstaticvoid main(String[] args){
Integer a =1;
Integer b =2;
System.out.println("a="+ a +",b="+ b);
Integer tmp = a;
a = b;
b = tmp;
System.out.println("a="+ a +",b="+ b);
}
輸出:
a=1,b=2
a=2,b=1
完美實現交換。但是請注意,這是一道面試題,要的就是考驗一些知識點。所以還是老老實實的實現 swap
方法吧。
有的同學可能會想, Integer
是一個包裝型別,是對Int的裝箱和拆箱操作。其實也是一個物件。既然是物件,直接更改物件的引用不就行了?
思路沒問題,我們首先看看實現:
privatestaticvoid swap(Integer numa,Integer numb){
Integer tmp = numa;
numa = numb;
numb = tmp;
System.out.println("numa="+ numa +",numb="+ numb);
}
輸出:
a=1,b=2
numa=2,numb=1
a=1,b=2
不出意外,沒有成功
這是什麼原因呢?
技術老手一看就知道問題出在形參和實參混淆了
JAVA的形參和實參的區別:
形參 顧名思義:就是形式引數,用於定義方法的時候使用的引數,是用來接收呼叫者傳遞的引數的。 形參只有在方法被呼叫的時候,虛擬機器才會分配記憶體單元,在方法呼叫結束之後便會釋放所分配的記憶體單元。 因此,形參只在方法內部有效,所以針對引用物件的改動也無法影響到方法外。
實參 顧名思義:就是實際引數,用於呼叫時傳遞給方法的引數。實參在傳遞給別的方法之前是要被預先賦值的。 在本例中 swap 方法 的numa, numb 就是形參,傳遞給 swap 方法的 a,b 就是實參
注意:
在 值傳遞
呼叫過程中,只能把實參傳遞給形參,而不能把形參的值反向作用到實參上。在函式呼叫過程中,形參的值發生改變,而實參的值不會發生改變。
而在 引用傳遞
呼叫的機制中,實際上是將實參引用的地址傳遞給了形參,所以任何發生在形參上的改變也會發生在實參變數上。
那麼問題來了,什麼是 值傳遞
和 引用傳遞
值傳遞和引用傳遞
在談 值傳遞
和 引用傳遞
之前先了解下 Java的資料型別有哪些
JAVA的資料型別
Java 中的資料型別分為兩大類, 基本型別
和 物件型別
。相應的,變數也有兩種型別: 基本型別
和 引用型別
基本型別
的變數儲存 原始值
,即它代表的值就是數值本身, 原始值
一般對應在記憶體上的 棧區
而 引用型別
的變數儲存 引用值
, 引用值
指向記憶體空間的地址。代表了某個物件的引用,而不是物件本身。物件本身存放在這個引用值所表示的地址的位置。 被引用的物件
對應記憶體上的 堆記憶體區
。
基本型別包括: byte
, short
, int
, long
, char
, float
, double
, boolean
這八大基本資料型別
引用型別包括: 類型別
, 介面型別
和 陣列
變數的基本型別和引用型別的區別
基本資料型別在宣告時系統就給它分配空間
int a;
//雖然沒有賦值,但宣告的時候虛擬機器就會 分配 4位元組 的記憶體區域,
//而引用資料型別不同,它宣告時只給變數分配了引用空間,而不分配資料空間:
String str;
//宣告的時候沒有分配資料空間,只有 4byte 的引用大小,
//在棧區,而在堆記憶體區域沒有任何分配
str.length();
//這個操作就會報錯,因為堆記憶體上還沒有分配記憶體區域,而 a = 1; 這個操作就不會報錯。
好了,Java的資料型別說完了,繼續我們的 值傳遞
和 引用傳遞
的話題。
先背住一個概念: 基本型別
的變數是 值傳遞
; 引用型別
的變數
結合前面說的 形參
和 實參
。
值傳遞
方法呼叫時,實際引數把它的值傳遞給對應的形式引數,函式接收的是原始值的一個copy, 此時記憶體中存在兩個相等的基本型別,即實際引數和形式引數,後面方法中的操作都是對形參這個值的修改,不影響實際引數的值
引用傳遞
也稱為 地址傳遞
, 址傳遞
。方法呼叫時,實際引數的引用(地址,而不是引數的值)被傳遞給方法中相對應的形式引數,函式接收的是原始值的記憶體地址
在方法執行中,形參和實參內容相同,指向同一塊記憶體地址,方法執行中對引用的操作將會影響到實際物件
通過例子來說話:
staticclassPerson{
int age;
Person(int age){
this.age = age;
}
}
privatestaticvoid test(){
int a =100;
testValueT(a);
System.out.println("a="+ a);
Person person =newPerson(20);
testReference(person);
System.out.println("person.age="+ person.age);
}
privatestaticvoid testValueT(int a){
a =200;
System.out.println("int testValueT a="+ a);
}
privatestaticvoid testReference(Person person){
person.age =10;
}
輸出:
int testValueT a=200
a=100
person.age=10
看見 值傳遞
a的值並沒有改變,而 引用傳遞
的 persion.age已經改變了
有人說
privatestaticvoid testReference(Person
相關推薦
你真的瞭解JAVA的形參和實參嗎?
「碼匠筆記」前幾天在頭條上看到一道經典面試題,引發了一些思考。也是寫這篇文章的導火索。背景請看題
Java中的形參和實參的區別以及傳值呼叫和傳引用呼叫
原文地址:http://blog.csdn.net/miniminiyu/article/details/52061401 名詞解析: 1.形參:用來接收呼叫該方法時傳遞的引數。只有在被呼叫的時候才分配記憶體空間,一旦呼叫結束,就釋放記憶體空間。因此僅僅在方法內有效
關於Java中的形參和實參的區別
類型 分配 不能 內部使用 rdquo 數量 運行時 常量 使用 形參出現在函數定義中,在整個函數體內都可以使用,離開該函數則不能使用。 實參出現在主調函數中,進入被調函數後,實參變量也不能使用。 形參和實參的功能是作數據傳送。發生函數調用時,主調函數把實參的
形參和實參的區別
返回 pre bsp 類型變量 目的 出現 分配內存 函數定義 class 形參:全稱為"形式參數"是在定義函數名和函數體的時候使用的參數,目的是用來接收調用該函數時傳如的參數. 實參:全稱為"實際參數"是在調用時傳遞個該函數的參數. 形參出現在函數定義中,在整個函數體內都
形參和實參
cor text nsf 數據 round ans post oat pla 形參出現在函數定義中,在整個函數體內都可以使用, 離開該函數則不能使用。實參出現在主調函數中,進入被調函數後,實參變量也不能使用。 形參和實參的功能是作數據傳送。發生函數調用時, 主調函數把實參的
3-12形參和實參
div war 16px pre 參數 多個 src bsp span # * 號可以有多個參數 *名字也可以自定義 規範 是 *args 按規矩來 *args 接收多個位置參數 轉換成元組 **kwargs 接收N個關
函數形參和實參
函數形參 pan nbsp spa color 形參 print class code def cal(x,y):。。形參 s=x**y 。。x的y次方 return s c=cal(2,3) ..實參 print(c) 函數形參和實參
JS中形參和實參的區別
JS中形參和實參的區別 from:https://blog.csdn.net/qq_33187168/article/details/50346465 形參出現在函式定義中,在整個函式體內都可以使用, 離開該函式則不能使用。 實參出現在主調函式中,進入被調函式後,實參變數也不能使用。
習題 :任意輸入十個數按大小排序;構造簡單數學運算模組(形參和實參)
任意輸入十個數字,按從大到小的順序排列 設定減法運算模組: 設定 乘除法混合運算 模組 int num = 3*chufa(num1, num2,num3); 這裡有這句指令,將該結果擴大三倍,40->120 *通過上面兩個程式引出形參和實參的概念: 通俗的來講,
C語言函式篇(二)形參和實參
參引數:形參和實參 ------------------------------- 形參實現一種資料傳入的介面 ,由實參 拷貝 給 形參 拷貝!!!!!!!!!!! 拷貝1: void func(int tmp
C++中的const限定符(5)——const形參和實參
1、當形參有頂層const時,傳給它常量物件或非常量物件都是可以的,這一點複合之前所說的,因為形參的初始值是拷貝了實參的。 2、在定義過載函式時,需要注意:對於形參是否是const的,是無法被編譯器所區分的。 void foo(int i){} void foo(co
Python的形參和實參
形參可以設定引數預設值,設定遵循從右至左原則 例如:fun(x=0,y=1),fun(x,y=1),但不可以是fun(x=1,y) 形參設定可以為數字字串變數、元組列表和字典等任意型別資料,元組列表的的形參是在變數名前加*,字典形參是在變數名前加** 例如:fun(
C語言第55課初始形參和實參
·第55課初始形參和實參 ·例子:自定義冪函式 #include<stdlib.h> //自行實現pow函式 //求第一個引數的n次冪 double power(double,int);//函式原型
函式返回值作為形參存在的問題以及形參和實參的區別
一、問題描述 若已定義的函式有返回值,則以下關於該函式呼叫的敘述中錯誤的是( D ) (A)函式呼叫可以作為獨立的語句存在。 (B)函式呼叫可以作為一個函式的實參。 (C)函式呼叫可以出現在表示式中。 (D)函式呼叫可以作為一個函式的形參。 解析:函式返回值存在暫存器
函式形參和實參特點
1. 形參變數只有在被呼叫時才分配記憶體單元,在呼叫結束時,即刻釋放所分配的記憶體單元。因此,形參只有在函式內部有效。函式呼叫結束返回主調函式後則不能再使用該形參變數。 2. 實參可以是常量、變數、表示式、函式等,無論實參是何種型別的量,在進行函式呼叫時,它們都必須具有確
C++函式——const形參和實參
頂層const: 表示任意的物件是常量。 底層const: 與指標和引用等複合型別有關。 對指標而言, 頂層const表示指標本身是個常量, 而底層const表示指標所指的物件是一個常量。 int i = 22; const
python獲得變數的名稱,獲得傳參(形參和實參)的名稱
1.需求和例子 需求:獲得變數的名稱 實現例子: aaa = '23asa' bbb = 'kjljl2' loc = locals() def get_variable_name(variable): print loc for key
c語言中形參和實參的區別?
形式引數和實際引數 函式的引數分為形參和實參兩種。在本小節中,進一步介紹形參、實參的特點和兩者的關係。形參出現在函式定義中,在整個函式體內都可以使用,離開該函式則不能使用。實參出現在主調函式中,進入被調函式後,實參變數也不能使用。形參和實參的功能是作資料傳送。發生函式呼叫
值型別和引用型別,形參和實參,傳值和傳引用
C# 中有兩種型別:引用型別和值型別。引用型別的變數儲存對其資料(物件)的引用(地址),而值型別的變數直接包含其資料(副本)。 對於引用型別,兩種變數可引用同一物件;因此,
[C#] 函式呼叫形參和實參之間加冒號
看到下面的語法,其他語言都沒見過這種語法 int GetValue(string prompt, int min, int max) { int result; do { result = SnapsEngine.R