java基礎(五)——數據類型和方法傳遞類型

在java中,分爲兩大類數據類型:值類型和引用類型。其中,值類型又可以稱爲基本數據類型

1.值類型(基本數據類型)(byte, short, int, long, float, double, char, boolean)

        基本數據類型又可以分爲數字類型(整數(byte,short,int,long)和浮點數(float,double))字符型(char)布爾型(boolean)

        1字節:byte

        2字節:short    char

        4字節:int    float

        8字節:long double

        至於布爾類型(boolean)並沒有明確指出佔用了多少字節

2.引用類型(除了基本數據類型之外的都是引用類型,枚舉是一種特殊的引用類型)

        引用類型一般是指指向對象的變量,如User這個類,執行了這句:User u = new User();之後,u就是一個引用類型,它保存的是User對象的堆內存地址,指向User這個對象


3.方法的值傳遞

        java中,所有的類型都會被分配到內存空間中,基本數據類型只有一塊存儲空間(被分配在棧中),而引用類型有2塊存儲空間(一塊是存儲引用變量的分配在棧中,另一塊存儲對象的分配在堆中)


以下摘自知乎大神@Intopass的答案(https://www.zhihu.com/question/31203609)

一、基本類型 和 引用類型的不同之處

int num = 10;
String str = "hello";

如圖所示,num是基本類型,值就保存在變量中。str是引用類型,變量中保存的只是對象的的地址,一般這種變量稱爲“引用”。引用指向實際對象,對象中保存着內容。

二、賦值運算符(=)的作用

num = 20;
str = "java";

對應基本類型num,賦值運算符會直接改變變量值,原來的值被覆蓋;

對應引用str,賦值運算會改變引用中保存的地址(指向另一個對象),原來的地址被覆蓋掉,但是原來的對象不會被改變(還是“hello”)

三、調用方法時發生了什麼?參數傳遞基本上就是賦值操作。

第一個例子:基本類型
void foo(int value) {
    value = 100;
}
foo(num); // num 沒有被改變

第二個例子:沒有提供改變自身方法的引用類型
void foo(String text) {
    text = "windows";
}
foo(str); // str 也沒有被改變

第三個例子:提供了改變自身方法的引用類型
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
    builder.append("4");
}
foo(sb); // sb 被改變了,變成了"iphone4"。

第四個例子:提供了改變自身方法的引用類型,但是不使用,而是使用賦值運算符。
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
    builder = new StringBuilder("ipad");
}
foo(sb); // sb 沒有被改變,還是 "iphone"。


下面是第3個例子圖解:

StringBuilder sb = new StringBuilder("iphone");
foo(sb);
void foo(StringBuilder builder) {
    builder.append("4");
}

開始在堆內存中創建了一個地址爲0x11的StringBuilder對象,對象內容爲“iphone”,sb保存着這個對象的地址(0x11),也就是sb指向這個對象;調用方法foo,實際上就是把sb的值0x11賦給了另一個StringBuilder類型的引用builder,此時builder的值也變成了0x11,與sb指向的是同一個對象。所謂值傳遞,其實就是把變量值賦給方法參數。


builder.append("4")之後,其實就是builder指向的對象的內容發生了改變。


下面是第4個例子的圖解:

StringBuilder sb = new StringBuilder("iphone");
foo(sb);
void foo(StringBuilder builder) {
    builder = new StringBuilder("ipad");
}

一開始,創建了sb對象,存儲的對象地址是(0x11),對象內容爲"iphone";調用foo方法,將sb的值(也就是0x11)賦給builder,然後builder也指向"iphone"


builder = new StringBuilder("ipad"); 之後,實際上是在堆內存中創建了一個新的StringBuilder的對象,對象裏面保存的值是:"ipad",而builder指向了這個新對象,所以builder的值變成了0x12,不再指向原來地址爲0x11的對象了



小結:java中的“=”符號是一種賦值操作,調用方法其實就是將值複製到形參上面。如果參數是基本類型變量,那麼就是對值的複製;如果參數是引用類型,那麼就是對地址的複製。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章