JAVA中的指針


  不同於CPP,JAVA中不需要程序員對指針進行操作。不過,這不代表JAVA沒有指針,事實上,JAVA的指針操作都被底層代碼封裝了。筆者在初學Java時,雖然就了解了形參,實參,StringBuffer這些概念,但一直只流於表面,對此沒有一個深度的認識。直到最近開始學習JVM虛擬機,才真正認識到了JAVA的精妙之處。

  首先,先說結論,Java中所有的基本數據類型的傳遞,都是按值傳遞,即傳遞的都是形參。除此以外的其他任何傳遞都是按地址傳遞,傳遞過去的都是實參,即cpp概念中的引用傳遞。最初筆者學習時也是就看到這,雖然知道了結論,但由於概念過於抽象,始終無法理解其本源(或者說內存模型中到底發生了什么)。Talk is cheap,show me the code。下面,我們來看一段代碼。

package point;

public class Formal {
    private void formal(int p){
        p=p*5;
        System.out.println(p);
    }

    public static void main(String[]args){
        int i=5;
        Formal fromal=new Formal();
        fromal.formal(i);
        System.out.println(i);
    }
}

  這段代碼在控制台輸出的結果是25和5,很顯然,按照正常的邏輯來說的話應該是25,25才對。為什么會出現這種結果?事實上,Java中對基本數據類型的傳遞都是值傳遞(不清楚為什么這樣,筆者的理解是基本數據類型在內存中的組合是有限的,這樣內存可以知道你需要傳遞的是什么,換而言之,它可以真正理解你要傳遞的東西,因此可以復制一份進行傳遞,這樣雖然會增大程序員的學習成本,但可以節省內存或者是增進效率。而非基本數據類型因為變化太多了,所以無法這么操作。不知道本人的理解有沒有誤差,才疏學淺,希望大神們多多指正)。通俗一點說,就是復制操作,在內存中,JVM只是把你操作的數據復制了一份給你傳遞到的對象,而不是把它本身傳遞了過去。

  這里要說一個特例,String類,貼一段代碼。

package point;

public class ActualString {
    private void actual(String color){
        color=color+" is red";
        System.out.println(color);
    }

    public static void main(String[]args){
        String car="myCar";
        ActualString actualString =new ActualString();
        actualString.actual(car);
        System.out.println(car);
    }
}

  這里控制台輸出結果是myCar is red,myCar,這不代表String傳遞的也是形參,或者是String是基本數據類型,事實上因為String類都是被final關鍵字修飾的,所以它的值不會變化,所以,字符串拼接之類的操作事實上只是在內存中開辟了一個新的空間,而原有的空間其實還存在,所以這就是為什么字符串的操作要使用StringBuffer類。

  下面我們看一下實參的代碼。

package point;

public class Actual {
    private void actual(int arr[]){
        arr[0]=arr[0]*5;
        System.out.println(arr[0]);
    }

    public static void main(String[]args){
        int a[]=new int[]{5};
        Actual actual=new Actual();
        actual.actual(a);
        System.out.println(a[0]);
    }
}

  毫無疑問,這次控制台輸出的結果是25,25。這里傳遞的就是對象本身的地址值,即實參,可以理解為剪切操作,將自身傳遞過去。

  

package point;

class Variable{
    public static Variable VAR=null;

    public int i;

    protected void a(int p){
        p=p*5;
        System.out.println(p);
    }

    public Variable(){
        i=5;
        Variable.VAR=this;
    }


}

public class FormalInActual {
    public static void main(String[] args){
        Variable variable=new Variable();
        System.out.println(variable.i);
        variable.a(variable.VAR.i);
        System.out.println(variable.VAR.i);
    }

}

  輸出結果是5,25,5。即使是像這樣把基本數據類型寫進方法里,通過方法傳遞,其傳遞的依舊是形參。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM