1. 程式人生 > >抽象類和介面的區別,內部類引用外部方法final引數,守護執行緒和使用者執行緒

抽象類和介面的區別,內部類引用外部方法final引數,守護執行緒和使用者執行緒

abstract class和interface有什麼區別?

        答:宣告方法的存在而不去實現它的類被叫做抽象類(abstract class),它用於要建立一個體現某些基本行為的類,併為該類宣告方法,但不能在該類中實現該類的情況。不能建立abstract 類的例項。然而可以建立一個變數,其型別是一個抽象類,並讓它指向具體子類的一個例項。不能有抽象建構函式或抽象靜態方法。(抽象類是不能例項化的,即不能被分配記憶體,而static修飾的方法在類例項化之前就已經別分配了記憶體,這樣一來矛盾就出現了:抽象類不能被分配記憶體,而static方法必須被分配記憶體。所以抽象類中不能有靜態的抽象方法。這和介面是一樣的,介面中的方法也只能是 public   abstract修飾的,不能加上static。)

Abstract 類的子類為它們父類中的所有抽象方法提供實現,否則它們也是抽象類。取而代之,在子類中實現該方法。知道其行為的其它類可以在類中實現這些方法。

1。試圖定義這樣的操作時,編譯器提示錯誤

  1. publicstaticabstract Some getSome();  

2。仔細看下面的例子程式碼

  1. class A{  
  2.     publicstaticvoid testP(){  
  3.        System.out.println("A");  
  4.        }  
  5.     publicvoid testM(){  
  6.        System.out.println("X"
    );  
  7.        }  
  8. }  
  9. class B extends A{  
  10.     publicstaticvoid testP(){  
  11.        System.out.println("B");  
  12.        }  
  13.     publicvoid testM(){  
  14.        System.out.println("Y");  
  15.        }  
  16. }  
  17. publicclass Test{  
  18.     publicstaticvoid main(String[] args){  
  19.        A a=new A();  
  20.        B b=new B();  
  21.        a.testP();//結果是 A
  22.        b.testP();//結果是 B
  23.        a.testM();//結果是 X
  24.        b.testM();//結果是 Y
  25.        a=b;  
  26.        a.testP();//結果是  A ,如果testP不是靜態的,那麼執行結果應該是B才對
  27.        b.testP();//結果是  B
  28.        a.testM();//結果是  Y
  29.        b.testM();//結果是  Y
  30.        }  
  31. }  
        介面(interface)是抽象類的變體。在介面中,所有方法都是抽象的。多繼承性可通過實現這樣的介面而獲得。介面中的所有方法都是抽象的,沒有一個有程式體。介面只可以定義static final成員變數。介面的實現與子類相似,除了該實現類不能從介面定義中繼承行為。當類實現特殊介面時,它定義(即將程式體給予)所有這種介面的方法。然後,它可以在實現了該介面的類的任何物件上呼叫介面的方法。由於有抽象類,它允許使用介面名作為引用變數的型別。通常的動態聯編將生效。引用可以轉換到介面型別或從介面型別轉換,instanceof 運算子可以用來決定某物件的類是否實現了介面。
=========================================================
int 和 Integer 有什麼區別
答:Java 提供兩種不同的型別:引用型別和原始型別(或內建型別)。int是java的原始資料型別,Integer是java為int提供的封裝類。Java為每個原始型別提供了封裝類。
原始型別和封裝類
boolean和Boolean
char和Character
byte和Byte
short和Short
int和Integer
long和Long
float和Float
double和Double
引用型別和原始型別的行為完全不同,並且它們具有不同的語義。引用型別和原始型別具有不同的特徵和用法,它們包括:大小和速度問題,這種型別以哪種型別的資料結構儲存,當引用型別和原始型別用作某個類的例項資料時所指定的預設值。物件引用例項變數的預設值為 null,而原始型別例項變數的預設值與它們的型別有關。


Collection 和 Collections的區別。 
Collection是集合類的上級介面,繼承與他的介面主要有Set 和List.。Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜尋、排序、執行緒安全化等操作。

談談final, finally, finalize的區別。 
final 用於宣告屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。
finally是異常處理語句結構的一部分,表示總是執行。都會執行,除非在前面出現system.exit(0)
finalize是Object類的一個方法,在垃圾收集器執行的時候會呼叫被回收物件的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉檔案等。

=========================================================

為什麼內部類方法引用外部類方法引數時引數要用final修飾?

1. 匿名內部類可以使用外部類的變數(區域性或成員變來那個)
2. 匿名內部類中不同的方法可以共享這些變數
根據這兩點資訊我們就可以分析,可能這些變數會在匿名內部類的欄位中儲存著,並且在構造的時候將他們的值/引用傳入內部類。這樣就可以保證同時實現上述兩點了。
事實上,Java就是這樣設計的,並且所謂匿名類,其實並不是匿名的,只是編譯器幫我們命名了而已。
Java對匿名內部類的實現是通過編譯器來支援的,即通過編譯器幫我們產生一個匿名類的類名,將所有在匿名類中用到的區域性變數和引數做為內部類的final欄位,同是內部類還會引用外部類的例項

public class InnerTest {
        /**
         * 方法中的內部類能不能訪問方法中的區域性變數,為什麼?
         * 
         * 答:如果區域性變數用final 關鍵字修飾,則可以訪問,否則不可以訪問。
         * 首先方法中定義有一個內部類,我們只是為了控制這個類的可見性,它並不是方法的一部分我們只是程式碼這樣寫,
         * 目的是為了控制內部類的可見性,編譯之後的結果,也會出現 外部類 和 內部類各自的位元組碼class檔案,
         * 這就說明內部類是一個獨立的個體,他們就是兩個類而已,他們各自都有自己的成員變數和方法。
         * 並且方法的屬性與內部類的生命週期不同. 方法執行完畢後,方法內的屬性也會隨之被銷燬,
         * 然而如果讓內部類在使用被銷燬的屬性這並不合理. 解決方法就是加上final關鍵字.
         * 在java中, 某個屬性一旦加上final關鍵字, 可以看作是常量,
         * 而常量的生命週期在程式的整個執行期間
         * 都是有效的. 所以可以引用, 不會出錯.
         * 
         * 
         * */
public static void main(String[] args) {
                
                doSomething();
        }
        public static void doSomething(){
        final int a =10;  //此處 的  a  必須用final 修飾,否則內部類將無法訪問a . 
        class Inner{
            public void seeOuter(){
                System.out.println(a);
            }
        }
        Inner in = new Inner();
        in.seeOuter();
    }
}
=========================================================
守護執行緒和使用者執行緒

Java有兩種Thread:“守護執行緒Daemon”與“使用者執行緒User”。
守護執行緒是一種“在後臺提供通用性支援”的執行緒,它並不屬於程式本體。
任何執行緒都可以是“守護執行緒Daemon”或“使用者執行緒User”。他們在幾乎每個方面都是相同的,唯一的區別是判斷虛擬機器何時離開。

守護執行緒是一種“在後臺提供通用性支援”的執行緒,它並不屬於程式本體。守護執行緒:守護執行緒則是用來服務使用者執行緒的,如果沒有其他使用者執行緒在執行,那麼就沒有可服務物件,也就沒有理由繼續下去。
setDaemon(boolean on)方法必須線上程啟動之前呼叫,當執行緒正在執行時呼叫會產生異常。isDaemon方法將測試該執行緒是否為守護執行緒。
setDaemon(boolean on)方法可以方便的設定執行緒的Daemon模式,true為Daemon模式,false為User模式。

值得一提的是,當你在一個守護執行緒中產生了其他執行緒,那麼這些新產生的執行緒不用設定Daemon屬性,都將是守護執行緒,使用者執行緒同樣。
舉個簡單的例子:後臺執行緒就是JVM(java虛擬機器),前臺執行緒,就是你寫的程式。當你在執行你的程式時,如果jvm關閉了,你的程式就執行不了了。當你的程式執行(前臺執行緒)完後,後臺執行緒也就自動關閉了。

使用後臺執行緒的優點,一般在什麼情況下會用到前臺執行緒?
完成你想完成的任務用前臺執行緒執行,例如比如把記憶體緩衝區的資料轉移到磁碟
非關鍵的任務用後臺執行緒執行,例如為記錄建立索引,或者計算word文字的個數

=========================================================
反射就是將java中的各個成分對映成為相應的java類!