面試-java知識基礎

下面是java的一些面試點,主要是基礎知識。java

1.  最多見的運行時異常    

  java運行時異常是可能在java虛擬機正常工做時拋出的異常。    

  java提供了兩種異常機制。一種是運行時異常(RuntimeExepction),一種是檢查式異常(checked execption)。

  檢查式異常:咱們常常遇到的IO異常及sql異常就屬於檢查式異常。對於這種異常,java編譯器要求咱們必須對出現的這些異常進行catch 因此 面對這種異常無論咱們是否願意,只能本身去寫一堆catch來捕捉這些異常。程序員

  運行時異常:咱們能夠不處理。當出現這樣的異常時,老是由虛擬機接管。好比:咱們歷來沒有人去處理過NullPointerException異常,它就是運行時異常,而且這種異常仍是最多見的異常之一。面試

  RuntimeExecption在java.lang包下,ajax

  ClassCastException(類轉換異常)算法

  IndexOutOfBoundsException(數組越界)spring

  NullPointerException(空指針)sql

  ArrayStoreException(數據存儲異常,操做數組時類型不一致)數據庫

  還有IO操做的BufferOverflowException異常編程

 

2.  String類是否能夠被繼承

  不能,final修飾的。

 

3. 一個".java"源文件中是否能夠包括多個類(不是內部類)

  能夠,可是一個文件中只能有一個public類,而且此public類必須與文件名相同。

4. 面向對象的編程方法具備四個基本特徵:

抽象
抽象就是忽略一個主題中與當前目標無關的那些方面,以便更充分地注意與當前目標有關的方面。

 繼承數組

類的重用。一個新類能夠從現有的類中派生,這個過程稱爲類繼承。派生類能夠從它的基類那裏繼承方法和實例變量,而且類能夠修改或增長新的方法使之更適合特殊的須要,提升代碼的重用行。

 封裝

   封裝是把數據和過程(對數據的操做)包圍起來,隱藏內部的實現細節,對數據的訪問只能經過已定義的方法 。

 多態

   多態性是指容許不一樣類的對象對同一消息做出響應。

 

5.spring的aop編程(aop Aspect Oriented Programming 面向切面編程

AOP能夠對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度下降,提升程序的可重用性,同時提升了開發的效率。

AOP/OOP區分

AOP、OOP在字面上雖然很是相似,但倒是面向不一樣領域的兩種設計思想。

OOP(面向對象編程)針對業務處理過程的實體及其屬性和行爲進行抽象封裝,以得到更加清晰高效的邏輯單元劃分。

而AOP則是針對業務處理過程當中的切面進行提取,它所面對的是處理過程當中的某個步驟或階段,以得到邏輯過程當中各部分之間低耦合性的隔離效果。這兩種設計思想在目標上有着本質的差別。

上面的陳述可能過於理論化,舉個簡單的例子,對於「僱員」這樣一個業務實體進行封裝,天然是OOP/OOD的任務,咱們能夠爲其創建一個「Employee」類,並將「僱員」相關的屬性和行爲封裝其中。而用AOP設計思想對「僱員」進行封裝將無從談起。

一樣,對於「權限檢查」這一動做片段進行劃分,則是AOP的目標領域。而經過OOD/OOP對一個動做進行封裝,則有點不三不四。

換而言之,OOD/OOP面向名詞領域,AOP面向動詞領域。

 

IOC和AOP的區別

IoC就是Inversion of Control,控制反轉。在Java開發中,IoC意味着將你設計好的類交給系統去控制,而不是在你的類內部控制。這稱爲控制反轉。

將對象的建立和獲取提取到外部。由外部容器提供須要的組件。

AOP 關注與主要的東西,也能夠說讓你只關注與業務,其餘的東西就讓AOP幫你完成。好比事務管理、持久化、資源池、系通通一的認證、權限管理等。容許經過分離應用的業務邏輯與系統級服務進行內聚性的開發。

 

6. 快速和歸併算法

 快速排序:

  設要排序的數組是A[0]……A[N-1],首先任意選取一個數據(一般選用數組的第一個數)做爲關鍵數據,而後將全部比它小的數都放到它前面,全部比它大的數都放到它後面,這個過程稱爲一趟快速排序。值得注意的是,快速排序不是一種穩定的排序算法,也就是說,多個相同的值的相對位置也許會在算法結束時產生變更。

  一趟快速排序的算法是:

  1)設置兩個變量i、j,排序開始的時候:i=0,j=N-1;

  2)以第一個數組元素做爲關鍵數據,賦值給key,即key=A[0];

  3)從j開始向前搜索,即由後開始向前搜索(j--),找到第一個小於key的值A[j],將A[j]和A[i]互換;

  4)從i開始向後搜索,即由前開始向後搜索(i++),找到第一個大於key的A[i],將A[i]和A[j]互換;

  5)重複第三、4步,直到i=j; (3,4步中,沒找到符合條件的值,即3中A[j]不小於key,4中A[i]不大於key的時候改變j、i的值,使得j=j-1,i=i+1,直至找到爲止。找到符合條件的值,進行交換的時候i, j指針位置不變。另外,i==j這一過程必定正好是i+或j-完成  的時候,此時令循環結束)。

  排序演示

  假設用戶輸入了以下數組:

下標

0

1

2

3

4

5

數據

6

2

7

3

8

9

  建立變量i=0(指向第一個數據), j=5(指向最後一個數據), k=6(賦值爲第一個數據的值)。

  咱們要把全部比k小的數移動到k的左面,因此咱們能夠開始尋找比6小的數,從j開始,從右往左找,不斷遞減變量j的值,咱們找到第一個下標3的數據比6小,因而把數據3移到下標0的位置,把下標0的數據6移到下標3,完成第一次比較:

下標

0

1

2

3

4

5

數據

3

2

7

6

8

9

  i=0 j=3 k=6

  接着,開始第二次比較,此次要變成找比k大的了,並且要從前日後找了。遞加變量i,發現下標2的數據是第一個比k大的,因而用下標2的數據7和j指向的下標3的數據的6作交換,數據狀態變成下表:

下標

0

1

2

3

4

5

數據

3

2

6

7

8

9

  i=2 j=3 k=6

  稱上面兩次比較爲一個循環。

  接着,再遞減變量j,不斷重複進行上面的循環比較。

  在本例中,咱們進行一次循環,就發現i和j「碰頭」了:他們都指向了下標2。因而,第一遍比較結束。獲得結果以下,凡是k(=6)左邊的數都比它小,凡是k右邊的數都比它大:

下標

0

1

2

3

4

5

數據

3

2

6

7

8

9

  若是i和j沒有碰頭的話,就遞加i找大的,尚未,就再遞減j找小的,如此反覆,不斷循環。注意判斷和尋找是同時進行的。

  而後,對k兩邊的數據,再分組分別進行上述的過程,直到不能再分組爲止。

  注意:第一遍快速排序不會直接獲得最終結果,只會把比k大和比k小的數分到k的兩邊。爲了獲得最後結果,須要再次對下標2兩邊的數組分別執行此步驟,而後再分解數組,直到數組不能再分解爲止(只有一個數據),才能獲得正確結果。

  代碼:

public class QuickSort {
    private static int par(int[]arr,int left,int right){
            int key=arr[left];

            while(left < right){
                //從最右邊開始找比key小的數
                while(left<right && arr[right]>=key)
                    right--;
                
                //把找到的數移到左邊
                arr[left]=arr[right];
                
                //從最左邊開始找比key大的數
                while(left<right && arr[left]<=key)
                    left++;
                
                //把找到的數移到右邊
                arr[right]=arr[left];
            }
            
            //最後,left等於right,將key至於中間,這樣,key以前的數,比key小,key以後的數,比key大
            arr[left]=key;
            return left;
    }
    
    private static void quickSort(int[]arr,int left,int right) {
        if(arr==null || arr.length==0 || left>=right){
            return ;
        }
        int pos=par(arr,left,right);
        quickSort(arr,left,pos-1);
        quickSort(arr,left+1,right);
    }
    
    public static void main(String[]args) {
        int[] arr={22,11,23,32,45,32,21,33,67,12};
        quickSort(arr,0,arr.length-1);
        for(int k:arr)
            System.out.print(k+" ");
    }
}

 

 歸併排序

  創建在歸併操做上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個很是典型的應用。將已有序的子序列合併,獲得徹底有序的序列;即先使每一個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併

歸 並過程爲:比較a[i]和a[j]的大小,若a[i]≤a[j],則將第一個有序表中的元素a[i]複製到r[k]中,並令i和k分別加上1;不然將第二 個有序表中的元素a[j]複製到r[k]中,並令j和k分別加上1,如此循環下去,直到其中一個有序表取完,而後再將另外一個有序表中剩餘的元素複製到r中 從下標k到下標t的單元。歸併排序的算法咱們一般用遞歸實現,先把待排序區間[s,t]以中點二分,接着把左邊子區間排序,再把右邊子區間排序,最後把左 區間和右區間用一次歸併操做合併成有序的區間[s,t]。

  歸併操做

  歸併操做(merge),也叫歸併算法,指的是將兩個順序序列合併成一個順序序列的方法。

  如 設有數列{6,202,100,301,38,8,1}

  初始狀態:6,202,100,301,38,8,1

  第一次歸併後:{6,202},{100,301},{8,38},{1},比較次數:3;

  第二次歸併後:{6,100,202,301},{1,8,38},比較次數:4;

  第三次歸併後:{1,6,8,38,100,202,301},比較次數:4;

  總的比較次數爲:3+4+4=11,;

  逆序數爲14;

 

  算法描述

  歸併操做的工做原理以下:

  第一步:申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列

  第二步:設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置

  第三步:比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置

  重複步驟3直到某一指針超出序列尾

  將另外一序列剩下的全部元素直接複製到合併序列尾

      

 代碼:

public class MergeSort {
    
    public static void mergeSort(int[] arr) {
    	if(arr==null || arr.length<=1){
    		return;
    	}
        mSort(arr, 0, arr.length-1);
    }

    public static void mSort(int[] arr, int left, int right) {
        if(left >= right)
            return ;
        int mid = (left + right) / 2;
        
        mSort(arr, left, mid); 		//遞歸排序左邊
        mSort(arr, mid+1, right); 	//遞歸排序右邊
        merge(arr, left, mid, right); //合併
    }
    
    /**
     * 合併兩個有序數組
     * @param arr 待合併數組
     * @param left 左指針
     * @param mid 中間指針
     * @param right 右指針
     */
    public static void merge(int[] arr, int left, int mid, int right) {
        //[left, mid] [mid+1, right]
        int[] temp = new int[right - left + 1]; //中間數組
        
        int i = left;
        int j = mid + 1;
        int k = 0;
        while(i <= mid && j <= right) {
            if(arr[i] <= arr[j]) {
                temp[k++] = arr[i++];
            }
            else {
                temp[k++] = arr[j++];
            }
        }
        
        while(i <= mid) {
            temp[k++] = arr[i++];
        }
        
        while(j <= right) {
            temp[k++] = arr[j++];
        }
        
        for(int p=0; p<temp.length; p++) {
            arr[left + p] = temp[p];
        }
        
    }
    
    public static void main(String[] args) {
    	int[] arr={1,98,33,31,35,2,55,78,44,3};
    	mergeSort(arr);
    	  for(int k:arr)
        	System.out.print(k+" ");
    }
}

 

7. 洗牌算法

   所謂洗牌算法,就是給你一個1到n的序列,讓你隨機打亂,保證每一個數出如今任意一個位置的機率相同,也就是說在n!個的排列中,每個排列出現的機率相同。

咱們考慮,當一個數被選以後,咱們是沒有必要在下一次隨機的時候再考慮它的,所以,咱們每次只從可選的數的集合中進行隨機,也就不用考慮是否會碰到已經選過的數了,這樣子直接將算法的複雜度降了一個數量級。

咱們考慮,當一個數被選以後,咱們是沒有必要在下一次隨機的時候再考慮它的,所以,咱們每次只從可選的數的集合中進行隨機,也就不用考慮是否會碰到已經選過的數了,這樣子直接將算法的複雜度降了一個數量級。

  

void MySwap(int &x, int &y)
{
    int temp = x;
    x = y;
    y = temp;
}

void Shuffle(int n)
{
    for(int i=n-1; i>=1; i--)
    {
        MySwap(num[i], num[rand()%(i+1)]);
    }
}

 

8. Java序列化

把對象轉換爲字節序列的過程—序列化。

把字節序列恢復爲對象的過程—反序列化。

對象的序列化主要有兩種用途:
  1) 把對象的字節序列永久地保存到硬盤上,一般存放在一個文件中;
  2) 在網絡上傳送對象的字節序列。

 

JDK類庫中的序列化API

  java.io.ObjectOutputStream表明對象輸出流,它的writeObject(Object obj)方法可對參數指定的obj對象進行序列化,把獲得的字節序列寫到一個目標輸出流中。
  java.io.ObjectInputStream表明對象輸入流,它的readObject()方法從一個源輸入流中讀取字節序列,再把它們反序列化爲一個對象,並將其返回。
  只有實現了Serializable和Externalizable接口的類的對象才能被序列化。Externalizable接口繼承自 Serializable接口,實現Externalizable接口的類徹底由自身來控制序列化的行爲,而僅實現Serializable接口的類能夠 採用默認的序列化方式 。
  對象序列化包括以下步驟:
  1) 建立一個對象輸出流,它能夠包裝一個其餘類型的目標輸出流,如文件輸出流;
  2) 經過對象輸出流的writeObject()方法寫對象。

  對象反序列化的步驟以下:
  1) 建立一個對象輸入流,它能夠包裝一個其餘類型的源輸入流,如文件輸入流;
  2) 經過對象輸入流的readObject()方法讀取對象。

 

9. String和StringBuffer的區別

  StringBuffer對象的內容能夠修改;而String對象一旦產生後就不能夠被修改,從新賦值後生成的新對象。

10. b/s和c/s的區別

硬件環境不一樣:

C/S 通常創建在專用的網絡上, 小範圍裏的網絡環境, 局域網之間再經過專門服務器提供鏈接和數據交換服務.  B/S 創建在廣域網之上的, 沒必要是專門的網絡硬件環境,例與電話上網, 租用設備. 信息本身管理. 有比C/S更強的適應範圍, 通常只要有操做系統和瀏覽器就行

 

對安全要求不一樣 :

  C/S 通常面向相對固定的用戶羣, 對信息安全的控制能力很強. 通常高度機密的信息系統採用C/S 結構適宜. 能夠經過B/S發佈部分可公開信息. 

  B/S 創建在廣域網之上, 對安全的控制能力相對弱, 面向是不可知的用戶羣.  

 

對程序架構不一樣:

  C/S 程序能夠更加註重流程, 能夠對權限多層次校驗, 對系統運行速度能夠較少考慮. 

  B/S 對安全以及訪問速度的多重的考慮, 創建在須要更加優化的基礎之上. 比C/S有更高的要求 B/S結構的程序架構是發展的趨勢, 從MS的.Net系列的BizTalk 2000 Exchange 2000等, 全面支持網絡的構件搭建的系統. SUN 和IBM推的JavaBean 構件技術等,使 B/S更加成熟. 

 

軟件重用不一樣:

C/S 程序能夠不可避免的總體性考慮, 構件的重用性不如在B/S要求下的構件的重用性好. 

  B/S 對的多重結構,要求構件相對獨立的功能. 可以相對較好的重用.就入買來的餐桌能夠再利用,而不是作在牆上的石頭桌子

 

系統維護不一樣 :

  系統維護是軟件生存週期中,開銷大, -------重要 

  C/S 程序因爲總體性, 必須總體考察, 處理出現的問題以及系統升級. 升級難. 多是再作一個全新的系統 

  B/S 構件組成,方面構件個別的更換,實現系統的無縫升級. 系統維護開銷減到最小.用戶從網上本身下載安裝就能夠實現升級.

 

處理問題不一樣:

  C/S 程序能夠處理用戶面固定, 而且在相同區域, 安全要求高需求, 與操做系統相關. 應該都是相同的系統 

  B/S 創建在廣域網上, 面向不一樣的用戶羣, 分散地域, 這是C/S沒法做到的. 與操做系統平臺關係最小.  

 

用戶接口不一樣 

  C/S 可能是創建的Window平臺上,表現方法有限,對程序員廣泛要求較高 

  B/S 創建在瀏覽器上, 有更加豐富和生動的表現方式與用戶交流. 而且大部分難度減低,減低開發成本.

 

11.private能夠修飾方法裏的變量嗎?

   不能夠,private咳喲用來修飾類變量。方法內的變量做用域是從這個變量聲明直到方法體結束,若是再使用private修飾的話二者就會衝突,因此不能在方法體內聲明一個變量爲private,並且在方法裏 聲明變量爲private也沒什麼意義,方法內聲明的變量的做用域原本就在方法體內,天然也不會被其它方法所訪問。

 

12.當一個線程進入一個對象的一個synchronized方法後,其它線程是否可進入此對象的其它方法?

能夠進入其餘非synchronized的方法,synchronized的方法不能夠的!
Java中的每一個對象都有一個鎖(lock)或者叫作監視器(monitor),當訪問某個對象的synchronized方法時,表示的將該對象上鎖,此時其餘任何線程都沒法再去訪問該synchronized方法了,直到以前的那個線程執行方法完畢後(或者是拋出了異常),纔將該對象的鎖釋放掉,其餘線程纔有可能再去訪問該synchronized方法。
若是一個對象有多個synchronized方法,某一時刻某個線程已經進入到了某個synchronized方法,那麼在該方法沒有執行完畢前,其餘線程是沒法訪問該對象的任何synchronized方法的。

13.對象的上轉型,子類重寫了基類的方法A,那麼上轉型對象操做的這個方法A,是基類的方法A?仍是子類的方法A?

  對象的上轉型,操做的是子類的方法A。上轉型對象只能操做基類的變量,子類繼承的方法和子類重寫的方法,不能使用子類新增的變量和方法。

 14 for循環裏能夠有boolean的表達式嗎?

  能夠。for( boolean1; boolean2&&條件表達式;boolean3)是正確的。

 15switch()的條件語句類型:

  byte、short、char、int、enum

  在jdk1.5上,Byte、Short、Character、Integer也支持。

 16 TreeMap是有序的map結構,HashMap不是,HashMap也是線程不穩定的。

 17hibernate操做數據庫的運行過程。

  1  讀取並解析配置文件

        Configuration conf = new Configuration().configure();

  2 讀取並解析映射信息,建立SessionFactory

       SessionFactory sf  = conf.buildSessionFactoty();

  3 打開Session

      Session session = sf.openSession;//sf.getCurrentSession();

  4 開始一個事務(增刪改操做必須,查詢操做可選)

      Transaction tx = session.beginTransaction();

  5 數據庫操做

     session.sava();

  6 提交事務(回滾事務)

     tx.commit();(tx.rollback();)

  7 關閉session

     session.close();

 18 定義內部類,外部怎麼調用?

  一:static聲明的內部類

  假設定義了一個類Outer,在Outer裏定義了一個內部類Inner。

class Outer{        // 定義外部類  
    private static String info = "hello world" ;    // 定義外部類的私有屬性  
    static class Inner{                // 使用static定義內部類爲外部類  
        public void print(){                // 定義內部類的方法  
            System.out.println(info) ;      // 直接訪問外部類的私有屬性  
        }  
    };  
    public void fun(){                      // 定義外部類的方法  
        new Inner().print() ;               // 經過內部類的實例化對象調用方法  
    }  
}

  那麼編譯後會生成Outer.class和Outer$Inner.class。

  經過Outer.Inner in=new Outer.Inner(); 訪問內部類。

  

  二:不使用statc聲明一個內部類

 

class Outer{        // 定義外部類  
    private static String info = "hello world" ;    // 定義外部類的私有屬性  
    class Inner{         // 使用static定義內部類爲外部類  
        public void print(){                // 定義內部類的方法  
            System.out.println(info) ;      // 直接訪問外部類的私有屬性  
        }  
    };  
    public void fun(){                      // 定義外部類的方法  
        new Inner().print() ;               // 經過內部類的實例化對象調用方法  
    }  
}

  經過 Outer o=new Outer();  Outer.Inner in=o.new Inner();訪問內部類。

  注意點:內部類不能含有static變量和方法,由於成員內部類的建立依賴於外部類對象。只有建立了外部類對象,才能建立內部類對象。

 

19 hibernate的inverse用法和含義

  Inverse是hibernate雙向關係中的基本概念。inverse的真正做用就是指定由哪一方來維護之間的關聯關係。當一方中指定了「inverse=true」,那麼那一方就有責任負責之間的關聯關係。

在set節點裏設置。

 

20 get和post的區別

  ①瀏覽器和服務器會對用get方式提交的數據進行限制,服務器會對用post方式提交的數據進行限制。

  ②post的請求數據放置在http請求包中。

  ③get的參數個數理論上沒有限制,可是瀏覽器和服務器會對用get方式提交的數據進行限制。

另外,get方式的提交的url採用ASCII編碼。

 

21 看看下面的運行結果

  1. public static void main(String args[]){ {

     String a; 

     System.out.println("a="+a);

    }

 2. public class InnerClassDemo03{  
        static String a;
        public static void main(String args[]){ 
              System.out.println("a="+a);
        }  
    }

  結果:第一個編譯會有問題,第二個運行輸出a=null。

  分析:第一個很好理解,使用前沒進行初始化,因此報錯。第二個的a實際上是成員變量,編譯器有個默認初始化,初始化爲null,因此有運行結果。

 

22 List、Set、Map的區別

  java集合(能夠存儲和操做數目不固定的一組數據,只能存放引用類型的數據,不能存放基本類型的數據,位於java.util包中)主要分爲三種類型,set、list、map。

  List:可自動擴展的數組。

  Set:沒有重複的數組。

23 java文件經編譯後,會生成字節碼(class)文件。

24 Spring裏集成的hibernate的DAO層繼承的哪一個類?hibernateDAOSupport

25 部署java應用的服務器有哪些?和ajax有關的框架有哪些?

  部署java應用:Tomcat、Resin、Jboss、Weblogic

  和ajax有關的框架:JQuery、DWR、Dojo、ExtJs、Mootools

26 通知垃圾回收的方法

  System.gc()方法強制垃圾回收

27 抽象類和接口的區別:

① abstract class 在 Java 語言中表示的是一種繼承關係,一個類只能使用一次繼承關係。可是,一個類卻能夠實現多個interface,實現多重繼承。接口還有標識(裏面沒有任何方法,如Remote接口)和數據共享(裏面的變量全是常量)的做用。abstract class和interface所反映出的設計理念不一樣。其實abstract class表示的是"is-a"關係,interface表示的是"has-a"關係

② 接口是公開的,裏面不能有私有的方法或變量,是用於讓別人使用的,而抽象類是能夠有私有方法或私有變量的。

③ 在abstract class 中能夠有abstract的成員方法,也能夠有非abstarct的成員方法,而在interface中全部的成員方法默認都是public abstract 類型的

④ 接口中定義的變量默認是public static final 型,且必須給其初值,因此實現類中不能從新定義,也不能改變其值。抽象類中的變量默認是 friendly 型,其值能夠在子類中從新定義,也能夠在子類中從新賦值。

⑤ 實現接口的必定要實現接口裏定義的全部方法,而實現抽象類能夠有選擇地重寫須要用到的方法,通常的應用裏,最頂級的是接口,而後是抽象類實現接口,最後纔到具體類實現。抽象類中能夠有非抽象方法。接口中則不能有實現方法。

 

28 transient使用小結

1)一旦變量被transient修飾,變量將再也不是對象持久化的一部分,該變量內容在序列化後沒法得到訪問。

2)transient關鍵字只能修飾變量,而不能修飾方法和類。注意,本地變量是不能被transient關鍵字修飾的。變量若是是用戶自定義類變量,則該類須要實現Serializable接口。

3)被transient關鍵字修飾的變量再也不能被序列化,一個靜態變量無論是否被transient修飾,均不能被序列化。

 

29 構造初始化順序

對象的初始化順序:(1)類加載以後,按從上到下(從父類到子類)執行被static修飾的語句;(2)當static語句執行完以後,再執行main方法;(3)若是有語句new了自身的對象,將從上到下執行構造代碼塊構造器(二者能夠說綁定在一塊兒)。

在Java中,子類的構造過程當中必須調用其父類的構造函數,是由於有繼承關係存在時,子類要把父類的內容繼承下來。但若是父類有多個構造函數時,該如何選擇調用呢?第 一個規則:子類的構造過程當中,必須調用其父類的構造方法。一個類,若是咱們不寫構造方法,那麼編譯器會幫咱們加上一個默認的構造方法(就是沒有參數的構造 方法),可是若是你本身寫了構造方法,那麼編譯器就不會給你添加了,因此有時候當你new一個子類對象的時候,確定調用了子類的構造方法,可是若是在子類構造方法中咱們並無顯示的調用基類的構造方法,如:super();  這樣就會調用父類沒有參數的構造方法。    

第二個規則:若是子類的構造方法中既沒有顯示的調用基類構造方法,而基類中又沒有無參的構造方法,則編譯出錯,因此,一般咱們須要顯示的:super(參數列表),來調用父類有參數的構造函數,此時無參的構造函數就不會被調用。

總之,一句話:子類沒有顯示調用父類構造函數,無論子類構造函數是否帶參數都默認調用父類無參的構造函數,若父類沒有則編譯出錯。

相關文章
相關標籤/搜索