Java 參數(shù)傳遞

Java方法傳參方式記住了兩點(diǎn)?;旧喜粫稿e誤。

  1. 方法內(nèi)修改基礎(chǔ)數(shù)據(jù)類型(數(shù)字類型或布爾類型)不會改變方法外的參數(shù);
  2. 方法內(nèi)修改對象(包含數(shù)組)狀態(tài)會同步修改方法方法外的參數(shù)。

程序片段1來驗(yàn)證第一點(diǎn):
public static void main(String[] args) {
    Integer a = 5;
    System.out.println("入棧前 a = " + a);
    calc(a);
    System.out.println("出棧后 a = " + a);    
 }
private static void calc(Integer a) {
    a = a * 3;
    System.out.println("棧內(nèi)計(jì)算 a = " + a);
}
程序的運(yùn)行結(jié)果為:
入棧前 a = 5
棧內(nèi)計(jì)算 a = 15
出棧后 a = 5

程序片段2來驗(yàn)證第二點(diǎn)
public static void main(String[] args) {
    Stu tom = new Stu(30, "tom");
    System.out.println("入棧前 tom = " + tom);
    doubleScore(tom);
    System.out.println("出棧后 tom = " + tom);

}

private static void doubleScore(Stu tom) {
    tom.score = tom.score * 2;
    System.out.println("棧內(nèi)計(jì)算 tom = " + tom);
}

private static class Stu {
    String name;
    int score;
    public Stu(int score, String name) {
        this.score = score;
        this.name = name;
    }
    @Override
    public String toString() {
        return "[ name='" + name + '\'' + ", score=" + score + ']';
    }
}
片段2的運(yùn)行結(jié)果為:
入棧前 tom = [ name='tom', score=30]
棧內(nèi)計(jì)算 tom = [ name='tom', score=60]
出棧后 tom = [ name='tom', score=60]

從兩段程序的結(jié)果看,片段1的基礎(chǔ)數(shù)據(jù)參數(shù)用值傳遞來解釋的通;片段2的對象參數(shù)用引用傳遞也行的通。

究竟參數(shù)傳遞采用哪種方式呢,特地翻了 Java編程思想第四版 第12章 傳遞和返回對象 中給出了解釋,Java中所有參數(shù)或自變量都是通過句柄的方式傳遞的,向方法中傳遞一個參數(shù)時,實(shí)際上傳遞的只是指向外部對象的一個句柄。

看清楚了嗎,人家根本不關(guān)心什么值傳遞、引用傳遞,實(shí)際上問題的關(guān)鍵是怎么理解 句柄。

  • Java按值傳遞任何東西。句柄當(dāng)做指針,傳遞對象就是拷貝對象的地址值,參數(shù)也指向該對象,方法內(nèi)對象狀態(tài)改外部對象也會改變;基礎(chǔ)數(shù)據(jù)類型就更明顯,基礎(chǔ)數(shù)據(jù)傳入方法會得到一個數(shù)據(jù)的副本,所以一切傳參都是按值傳遞。
  • Java主要按值傳遞,但對象卻是引用傳遞。句柄看做對象的一個“別名”,由于對象傳入方法沒有獲得一個本地副本,所以對象傳遞顯然不是值傳遞,而是引用傳遞。
    句柄 的理解不同帶來了不同的結(jié)果,原書的作者直接回避了這個問題,也許java的設(shè)計(jì)者壓根沒有考慮這個問題,才會后面的爭議。

還有一點(diǎn)一定要記住,記為第三點(diǎn):
  1. 方法不能改變對象參數(shù)的引用
程序片段3來驗(yàn)證第3點(diǎn):
public static void main(String[] args) {
    Stu tom = new Stu(30, "tom");
    System.out.println("入棧前 tom = " + tom);
    convert(tom);
    System.out.println("出棧后 tom = " + tom);
}
private static void convert(Stu tom) {
    tom = new Stu(50, "jack");
    System.out.println("棧內(nèi)計(jì)算 tom = " + tom);
}
程序片段3來運(yùn)行結(jié)果:
入棧前 tom = [ name='tom', score=30]
棧內(nèi)計(jì)算 tom = [ name='jack', score=50]
出棧后 tom = [ name='tom', score=30]

總結(jié)

不管一切按值傳遞,還是主要按值傳遞,從這三個特點(diǎn)來講都解釋的通,沒必要為概念糾結(jié),明白特性才是關(guān)鍵!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容