1.對象是數(shù)據(jù)和行為的基礎(chǔ)
舉例:
public Class Cat{
//數(shù)據(jù)
String name
//行為
private void meow(){
print('喵')
}
}
- 一切使用new運(yùn)算符創(chuàng)造出來的都是對象
new Cat()
new Integer()
對象是由什么組成的?
- 所有的對象都在堆上分配
- 創(chuàng)建對象時發(fā)生的一切
public Class Home{
Cat cat
public Home(Cat cat){
this.cat = cat
}
public static void main(String[] args){
new Home(new Cat(age: 1, name: "咪咪")
}
}
public Class Cat{
int age
String name
private void meow(){
print('喵')
}
}
在執(zhí)行完
new Home(new Cat(age: 1, name: "咪咪")
這句語句之后粤蝎,內(nèi)存發(fā)生了以下變化:
首先在堆中會創(chuàng)建一個新的Home類對象刹前,其中存放Cat類的地址(reference)脉幢,然后這個reference指向真正的Cat類對象爸舒,在Cat類對象中存放了4個字節(jié)的age, 和指向String的地址浇雹。
三步新建對象
1.在堆上分配空間
2.執(zhí)行必要的初始化工作
原生類型會被初始化為0
引用類型會被初始化為null
3.執(zhí)行構(gòu)造器函數(shù)
方法的重載overload
啥是重載?
在類中寫多個重名的方法硅堆,但是參數(shù)表不一樣屿储,例如下面的printName方法
public class Cat{
//方法
void printName(){}
void printName(String name){
}
public static void main(String[] args){
Cat cat = new Cat();
cat.printName();
}
}
如何區(qū)分同名的不同重載方法?
- 根據(jù)傳遞參數(shù)的類型區(qū)分
如果調(diào)用時 是cat.printName() 則調(diào)用第一個方法
如果調(diào)用時 是cat.printName("喵喵") 則調(diào)用第二個方法
2.但是根據(jù)類型區(qū)分重載方法渐逃,可能會存在一些坑
在Java中够掠,int 和Integer是可以自動轉(zhuǎn)換的
所以說,如果一個方法的調(diào)用可以匹配多個方法的聲明茄菊,應(yīng)該調(diào)用哪個方法呢疯潭?
例如 調(diào)用Cat.f(2)
傳入的2是int類型
而int可以裝箱成Integer,而integer又可以轉(zhuǎn)換成Number面殖,那么Java會如何選擇竖哩?
答案是 最匹配的方法會被調(diào)用
那么如果兩個重載方法匹配的程度相同呢?
編譯器會報(bào)錯畜普,必須強(qiáng)制為參數(shù)指定類型
舉例:
public class Cat{
public static void main(String[] args){
Cat cat = new Cat();
cat.f(null);
}
void f(Integer i){}
void f(ArrayList i){}
}
這里null 會同時匹配Integer和ArrayList
可以給方法設(shè)定默認(rèn)值嗎期丰?
我的目標(biāo)是在調(diào)用Cat.meow()方法時,即使不傳遞name參數(shù)吃挑,也能自動打印出默認(rèn)值钝荡。
但是這在Java中不可以的,但是可以用重載曲線救國
public class Cat{
public static void main(String[] args){
Cat cat = new Cat();
cat.meow();
cat.meow("喵喵喵");
}
public void meow(){
meow("貓的默認(rèn)名字");
}
public void meow(String value){
System.out.println(value);
}
}
重載meow()函數(shù)舶衬,并在其中調(diào)用meow(String name) 即可實(shí)現(xiàn)
構(gòu)造器的重載
普通的方法可以初始化埠通,那么構(gòu)造器可以重載嗎?
可以逛犹!
需要使用this()
public class Cat{
int age;
String name;
//創(chuàng)建一只默認(rèn)的貓端辱,1歲,名為嘻嘻嘻嘻
Cat(){
this("嘻嘻嘻嘻");
}
//創(chuàng)建一只默認(rèn)的貓虽画,1歲舞蔽,名為name
Cat(String name){
this(20, name);
}
//創(chuàng)建一只指定了age, name的貓
Cat(int age, String name){
this.age = age;
this.name = name;
}
public static void main(String[] args) {
new Cat();
}
}
在調(diào)用時,會先調(diào)用Cat() --> Cat(Name) --> Cat(age, name)
對象初始化的順序
1.靜態(tài)成員的初始化
2.靜態(tài)初始化塊
3.成員的初始化
4.初始化塊
初始化塊就是{}包含的內(nèi)容
public class Cat{
int age;
String name;
//初始化塊
{
for(int i = 0; i < 100; i++){
age += 1;
}
}
//初始化塊結(jié)束
Cat(int age, String name){
this.age = age;
this.name = name;
}
public static void main(String[] args) {
new Cat(2,"ASX");
}
}
對象的生命周期
1.如果一直新建對象码撰,內(nèi)存會不會爆炸渗柿?
可能不會
2.對象的內(nèi)存如何被回收?
JVM中的garbage collection會回收
3.JVM怎么知道哪個對象沒有被用到脖岛?
通過引用鏈(GC Roots)
JVM沿著GC root可以達(dá)到的數(shù)據(jù)都是有用的朵栖,其余的都是垃圾,會被回收
其中最關(guān)鍵的GC Root就是方法棧中的變量的引用鏈