一、基本數據類型
- byte、short、int、long(整數類型)
- float、double(浮點數類型)
- char(字符型)
- boolean(布爾類型 )
Java數據大多數存放在堆棧中。
-
棧區:存放局部變量,對象聲明的引用等。
-
堆區:存放new關鍵字創建的類(包含成員變量)和數組等。
堆與棧的優缺點
-
棧的優點:棧數據可以共享,存取速度比堆快。 缺點是:存在棧中數據大小與生命周期是確定的。
-
堆的優點:可以動態分配內存大小,生存期也不必事先告訴編譯器。缺點是:存取速度較慢。
舉個栗子,如下圖:
-
編譯器會在棧中創建一個a的引用,然后在棧中查找字面值為5的引用,將a指向5的地址,若沒有找到,就會開辟一個地址來
存放字面值5,然后再將a指向該地址。定義int c=5;因為棧中存在字面值5,所有c會直接指向5的地址。令a=8,因為棧中
沒有字面值為8的引用,所有會開辟一個地址存放8,a會重新指向8的地址,c的指向不受a影響,c的值不會改變。
二、引用數據類型
1. Class(類)
2. Interface(接口)
3. Array(數組)
-
Java是面向對象語言,它為每一個基本數據類型都做了相應的包裝類(見上一個表格),也就是實現了基本類型變量到包裝類
對象的轉換。引用類型一般通過new關鍵字來創建,(對象)它存放在內存的堆中,可以在運行時動態的分配內存大小。引用
變量中存放的是變量內容的地址,它存放在內存的棧中。當引用類型變量不被使用時,Java內部的垃圾回收器GC會自動回收。
1.代碼示例-Class:
public class Demo {
String Name;
int Age;
double Score;
Demo(String Name,int Age,double Score){
//定義帶三個參數的構造函數,進行初始化
this.Name=Name;
this.Age=Age;
this.Score=Score;
};
public static void main(String[] args) {
Demo d1=new Demo("小吳",20,98);
Demo d2=new Demo("小天",19,80);
}
}
- 引用本身是保留在棧中的,而引用所指的對象是存放在堆中的。
2.代碼示例-Interface
interface Animal {//定義Animal接口
public void eat();
public void speak();
}
public class Dog implements Animal {//Dog類實現Animal接口
public void eat() {
System.out.println("我喜歡吃骨頭!");
}
public void speak() {
System.out.println("汪汪汪!");
}
public static void main(String[] args) {
Dog d=new Dog();
d.eat();
d.speak();
}
}
-
編寫接口的方式和類很相似,但是它們屬於不同的概念。類描述對象的屬性和方法。接口則包含類要實現的方法。
-
接口與類的區別:
-
接口不能用於實例化對象。
-
接口沒有構造方法。
-
接口中所有的方法必須是抽象方法。
-
接口不能包含成員變量,除了 static 和 final 變量。
-
接口需要被類實現。
-
接口支持多繼承。
3.代碼示例-Array
public class Array {
public static void main(String[] args) {
int[] myList = new int[] {5,2,0,1,3,1,4};
for(int list: myList) {
System.out.print(list);
}
}
}
- 在以上代碼中,myList變量存放了數組對象的引用,它存放到棧中,而數組對象所占的空間在堆上被分配(和上圖一樣)。
拓展1:
-
方法的返回值類型為類名:返回該類的對象。
-
方法的返回值類型為接口名:返回該接口的實現類的對象。
public static Comparable findMax(Comparable[] arr) {
int maxIndex=0;
for(int i=1;i<arr.length;i++)
if(arr[i].compareTo(arr[maxIndex])>0)
maxIndex=i;
return arr[maxIndex];
}
-
上述代碼中,傳遞參數為實現了Comparable接口的對象數組,方法返回的是Comparable接口的實現類的對象。
-
我們通常會使用Object、接口類型等方式來表示泛型,目的是支持代碼重用。
拓展2:自動裝箱與拆箱
-
自動裝箱:如果一個int型量被傳遞到需要一個Integer對象的地方,編譯器將在幕后插入一個對Integer構造方法的調用。
-
自動裝箱:如果一個Integer對象被放到需要int型量的地方,則編譯器將在幕后插入一個對intValue方法的調用。
注:參考《數據結構與算法分析Java語言描述》和 菜鳥教程