JAVA新手教學 -7 參照型別變數與回傳值
各位還記得我們在JAVA新手教學 -2裡提到的原生型別變數嗎?今天我們要來談談變數的另一種型別─參照變數,以及參照變數對回傳值的特性。想必大家差不多都忘了原生型別是甚麼東西了吧,就讓我們來一起複習吧!
參照型別變數:
在JAVA新手教學 -2裡,我們有提到原生型別以下8種,非以下8種型別的變數皆為參照變數。
型別 值的類別 記憶體空間
- byte 整數 1byte
- short 整數 2bytes
- int 整數 4bytes
- long 整數 8bytes
- float 實數(浮點數) 4bytes
- double 實數(浮點數) 8bytes
- char 單一字元 2bytes
- boolean true or false 1bit
那麼參照和原生到底差在哪裡?直接舉例子能夠讓你更快瞭解。看下圖,你能分出原生和參照的差別嗎?
在JAVA新手教學 5 – 類別與方法的宣告及使用裡,有提到如何產生類別的實體物件。
- 變數宣告,宣告此變數為屬於某一類別的物件。
- 保留字new下令在記憶體中產生實體物件。
- 語法:類別名稱+物件名稱+=+new+類別名稱+(引數)。
由此可知由類別所宣告的變數皆為參照變數,再經由new產生實體物件。以Scanner input=new Scanner(System.in);為例子,這段程式碼主要是要產生一個物件input,讓你可以利用input呼叫各種輸入方法,例如 int a1=input.nextInt();。
那麼參照變數有哪些特徵呢?
- 儲存特定物件的參照位址
- 本身不保存資料,而是指向其物件所儲存的變數或資料。
- 內定值為null。
- 使用設定預算子(=)時,透過複製取得另一變數的參照位址。
參照位址又是甚麼?以下圖為例,有一個類別名稱是Calculator,類別內有一int型別屬性變數x,其值為10。在記憶體內分別位於CX001和CX004,原生型別的變數會直接指向值。但參照型別就不一樣了,我們在有main方法的Test1類別中產生Calculator類別的物件c1,c1這個物件內包含了x變數,c1(AW001)指向一個值(AW003內的值),這個值是個位址(CX001),再指向該位址的值(也就是x),因此我們稱c1為參照型別變數。
參照型別變數的值(位址)也可以複製給另一個物件,如下圖。
接著我們來結合上一章節講解的setget方法來告訴大家,這兩者除了語法以外還有甚麼不同的地方吧!大家可以試試看下方的兩個類別推論出執行結果。
public class Employee{
private int age=0;
public void setAge(int a){age=a;}
public int getAge(){return age;}
}
public class company{
public static void main(String args[]){
Employee Sean=new Employee();
Sean.setAge(18);
System.out.print(Sean.getAge());
Employee Jojo=Sean;
Jojo.setAge(20);
System.out.print(Jojo.getAge());
System.out.print(Sean.getAge());
}
}
如果你推論出的結果是18,20,18,那麼很抱歉你答錯了!答案是18,20,20,為甚麼我明明只有更改Jojo的年齡,Sean的年齡也跟著改變了呢?就讓我來幫你解惑吧!首先剛剛有提到參照型別變數的值(位址)也可以複製給另一個物件,我將Sean的值複製給了Jojo,這讓Jojo也有了跟Sean一樣的位址,隨後我去更改了該位址內age的值導致了Jojo變成了20,因為Sean也指向同一個位址,所以他的值也跟著改變,如下圖所示。
!!!!例外!!!!
通常物件都需要藉由new來初始化,而文字變數(String)卻不需要,String也是參照型別的變數,屬於java.lang套件。例如String a=”肥柴”,系統會將雙引號之間的符號自行產生內容為肥柴的文字物件。
回傳值特性:
public int method1(){…….}
public boolean method2{…….}
這些都是我們之前學過,具有回傳型別的方法。不過基本上回傳的都是原生型別,那麼參照型別是否也可以呢?答案是可以的,我們只需要在原本寫回傳型別的地方寫上該參照變數所在類別的名稱即可。舉個例子假設我今天要利用方法來產生物件,可以使用下列程式碼。
public Employee method3{
Employee e1=new Employee();
return e1;
}
不過要注意的是,因為是回傳參照變數的值,所以值是一個位址。這一點請別忘記。