面向對象(上)部分問題的理解

什麼是構造方法
構造方法是一個對象在創建時直接自動執行的對變量進行初始化的方法。構造方法的函數名和類名相同,沒有返回值和返回類型,但可以被public和private修飾。如果沒有自定義構造方法則系統會給出默認無參構造方法,構造方法也可以自定義並重載。

什麼是抽象
抽象時從被研究對象中捨棄個別的,非本質的或與研究主旨無關的次要特徵,抽取與研究有關的共性內容加以考察,形成對研究問題正確、簡明扼要的認識。
如:從人和馬中抽象出來共同的動物屬性。

對象位於內存何處
在程序運行時,類會被加載到方法區中,而其中的靜態變量加載到方法區的靜態存儲區中。在類用new創建對象時,對象會被放置在堆內存中,在堆中開闢空間存放對象的域變量,而對象的方法實質上還是在調用類在方法去存儲的方法。

聲明能引用對象的實質是什麼
創建引用時,方法中引用會被加載到棧中,引用保存的是對象在堆中的地址,相當於一個遙控器去操縱這個對象。

對象和基本數據類型作爲參數傳遞時的不同之處
這就類似c++中的值傳遞和引用傳遞,基本數據類型傳遞的是一個副本,這個副本對本體沒有任何影響,而引用傳遞則是將這個引用的對象傳遞給參數中的引用,兩個引用指向的是同一個對象,所以形參可以改變對象中的變量。

public static void add(int a) {
		a++;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int x=3;
		add(x);
		System.out.println(x);//輸出3
		
}
	
class A{
	int x=1;
	void fA(){
		x++;
	}
}
public class test {

	public static void add(A a) {
		a.fA();
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		A a1=new A();
		System.out.println(a1.x);//輸出1
		add(a1);
		System.out.println(a1.x);//輸出2
		
}
	
}

對象在什麼條件下成爲垃圾
Java和c++對象很大的一個不同之處在於c++的類在不用時需要主動delete,但是Java則不用,會由Java虛擬機自動回收,那麼什麼時候回收,又怎麼去判斷是否回收了呢?
JVM會在一個對象沒有被任何引用所關聯時將其判斷爲垃圾對象,但此時這個對象並不會被立即回收,而是會等待JVM去進行一次清理內存時回收,JVM會在內存不足時立即清理一次內存,此時對象將會被回收。而怎麼證明被回收了呢,其中一個方法就是使用finalize方法,利用這個方法去告訴使用者該對象已經被回收了。finalize方法相當於析構函數,會在對象被回收時調用,但是這個回收的時間並不確定,如果需要回收,也可以使用system.gc()方法進行顯式回收。

class A{
	protected void finalize() throws Throwable {
		System.out.println("我死了QAQ");
	}
}
public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		A a1=new A();
		a1=null;
		System.gc();
		System.out.println("over");
}
}
//輸出:
//over
//我死了QAQ

從上面的例子中我們可以看出gc()方法釋放了對象A的內存,析構方法finalize被調用,但是有一個問題出現了,over比finalize先被調用。這是因爲JVM對有finalize方法的對象的回收實際上是調用了一個優先級低的Finalizer線程去執行它,這個線程執行需要一定時間,所以就算使用gc方法也不能保證立即就能回收。並且對象的finalize方法還有可能讓對象死裏逃生,這個這裏就不詳細論述了。

class A{
	protected void finalize() throws Throwable {
		System.out.println("我死了QAQ");
	}
}
public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		A a1=new A();
		a1=null;
		System.gc();
		System.gc();
	    try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
        }
		System.out.println("over");
}
}
//輸出:
//我死了QAQ
//over

這個例子使用了延時函數,延遲了一小段時間,這樣就可以看出finalize在over之前被調用了。

final修飾符都有什麼作用
final修飾符可以作用在類、方法、和變量之前。
當修飾一個類時,表示這個類是一個最終類,不可以被繼承。
當修飾一個方法時,表明這個方法不可被覆蓋,即子類繼承時不可以被重寫。
當修飾一個變量時,表明這個變量不可被修改,可以認爲這是一個常量。

static方法的和屬性的特點
見之前的博客:
https://blog.csdn.net/qq_43791007/article/details/100623603

Application程序執行時爲何不帶後綴名
因爲此時執行的是一個類,會自動尋找“.class”,不可以帶後綴。

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