Java經典知識點&面試題整理02

這一期我們繼續介紹Java相關的面試題,這一次還是5道題。下面我們開始一一進行解答。

1.請簡要比較接口和抽象類的區別。

①:接口中不能包含任何非抽象方法,但是抽象類可以包含

②:接口可以實現多繼承,抽象類不可以實現多繼承

③:抽象類要被子類繼承,接口要被類實現;

④:接口裏定義的變量只能是公共的靜態的常量,抽象類中的變量是普通變量

⑤:抽象類可以有構造器,接口不能有構造器。

具體可參照博客鏈接https://www.cnblogs.com/jmyyyy/p/10960271.html,這裏只列出常見的幾種區別了。

2.(1)什麼是內部類?請簡要說說內部類有哪些特點?

(2)什麼是靜態內部類?其有什麼特點?

(1)內部類就是定義在另一個類中內部的類,內部類的特點有:

①:內部類可以訪問其外部類的所有屬性和方法;

②:外部類無法直接訪問內部類的屬性和方法,需要實例化纔可以;

③:內部類如果和外部類有同名的屬性,優先執行內部類的屬性

④:內部類不能定義static的變量。

下面我們寫一個簡單的例子,加深對內部類的理解。代碼如下:

public class Outer {
	
	private int varOuter = 100;
	private double x = 20.5;
	
	/**
	 * 內部類:對於其他類中的類是隱藏的,不能被訪問;
	 * 不能定義static的變量,
	 * 內部類可以直接訪問到外部類的變量,無需實例化; 
	 * 但是外部類想要訪問到內部類,需要實例化,
	 * 如果類不想被其他類使用,可以聲明爲內部類.
	 * 內部類如果和外部類有同名的屬性,優先執行內部類的屬性.
	 * @author autumn_leaf
	 *
	 */
	class Inner {
		int varInner = 200; //變量定義
		double x = 50.5;//內部變量x
		//方法定義
		public void showOuter() {
			System.out.println(varOuter);//調用外部類的變量
			System.out.println(x);//50.5
			//20.5
			System.out.println(Outer.this.x);//調用外部類的同名屬性
		}
	}
	
	//外部類引用內部類必須要實例化
	public void showInner() {
		Inner i = new Inner();
		System.out.println(i.varInner);//200
		i.showOuter();//100
	}
	
	public static void main(String[] args) {
		Outer outer = new Outer();
		outer.showInner();
	}

}

(2)靜態內部類就是用static標識的內部類,其特點是可以定義靜態成員和非靜態成員,而非靜態內部類只能定義非靜態成員

下面寫一個小的例子來簡要介紹靜態內部類的用法,代碼如下:

public class OuterStatic {
	
	private int varOuter = 20;
	//內部類可用修飾符:default public private protected
	/**
	 * 定義一個靜態內部類,可以定義靜態的變量,也可以定義非靜態的變量
	 * 非靜態內部類不可以定義static的變量
	 */
	private static class innerStatic {
		static int a;
		int varInner = 200;
		public void showOuter() {
			//靜態內部類不能調用外部非static修飾的內容
			//System.out.println(varOuter);
			//可以調用類中定義的非靜態變量
			System.out.println(varInner);
		}	
	}
		
	public static void main(String[] args) {
		//調用靜態內部類
		OuterStatic.innerStatic oi = new OuterStatic.innerStatic();
		System.out.println(oi.varInner);
		System.out.println(oi.a);
		//調用非靜態內部類
		Outer o = new Outer();
		Outer.Inner i = o.new Inner();
		System.out.println(i.varInner);
		i.showOuter();
	}
}

3.請簡要說說final關鍵字的用法。

final可以修飾屬性、方法以及類,其中:①被修飾的變量不能夠被重新賦值,可以在聲明時賦值,或者在構造器中賦值;②被修飾的類不能夠被繼承;③被修飾的方法不能在子類中被覆蓋,即不能夠被修改。下面寫一個簡單的例子,代碼如下:

public final class FinalDemo {
	int a;//默認值爲0
	static final int b = 1;//必須有值
	//如果當前不是final修飾的類,那麼可能發生繼承關係
	//父類被final修飾的方法,子類繼承的時候,不能進行覆蓋
	static final void test() {
		System.out.println("不能被修改!");
	}	
}

4.試比較Object類型與String類型equals方法的區別。

Object類型的equals方法只會比較是否是同一個對象,而String類型的equals方法優先判斷是否是同一個對象,若不是同一個對象,則按位進行比較。

下面寫一個簡單的例子來顯示剛剛的說明,代碼如下:

public class ObjectSample {
	
	public static void main(String[] args) {
		String str1 = new String("haha");
		String str2 = "haha";
		String str3 = "haha";
		System.out.println(str1 == str2);//false str1進行了實例化,所以這裏不是同一個對象
		System.out.println(str2 == str3);//true 指向同一個對象
		//Object類型equals方法只會比較是否是同一對象
		//String類型equals方法優先判斷是否同一個對象,若不是同對象,則按位進行比較
		System.out.println(str1.equals(str2));//true
	}

}

結果我已經註釋在後面了,下面我們查看一下equals方法的底層源碼,如下:

 public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

5.嘗試對一個郵箱進行檢測並拋出異常,要求用戶名長度不能超過12位(@符號前面爲用戶名),@符號後面必須以.com或者.cn結尾,試寫出簡要的檢驗代碼。

我們首先定義一個異常EmailCheckException,代碼如下:

public class EmailCheckException extends Exception{

	private static final long serialVersionUID = 1L;

	public EmailCheckException(String msg) {
		super(msg);
	}

}

然後郵箱檢測類EmailCheck代碼如下:

import java.util.Scanner;

/**
 *  郵箱檢測
 * @author autumn_leaf
 *
 */
public class EmailCheck {
	
	public static void checkEmail(String email) throws EmailCheckException {
		int unameLen = email.indexOf('@');
		int begin = email.indexOf('@');
		int end = email.lastIndexOf('@');
		int dot = email.indexOf('.');//從開始位置.出現的位置
		//用戶名長度判斷
		if(unameLen > 12) {
			throw new EmailCheckException("Email用戶名長度超過12位!");
		}else if(begin != end) {
			throw new EmailCheckException("Email中包含多個@!");
		}
		//未出現@或者@在開頭或者@在結尾
		else if(begin == -1 || begin == 0 || begin == email.length()-1) {
			throw new EmailCheckException("@沒有出現或者@位置不對!");
		}else if(begin > dot) {
			throw new EmailCheckException("@與.出現的位置不對!");
		}else if(!email.endsWith(".com") && !email.endsWith(".cn")){
			throw new EmailCheckException("郵箱結尾不是.com或者.cn!");
		}
	}

	public static void main(String[] args) {
		System.out.println("請輸入郵箱:");
		Scanner sc = new Scanner(System.in);
		String email = sc.nextLine();
		try {
			checkEmail(email);
		} catch (EmailCheckException e) {
			e.printStackTrace();
		}
		System.out.println("操作結束!");
	}
}

上述代碼中我們先自定義一個郵箱異常類,然後定義一個郵箱檢測類,在函數中我們考慮以下幾點:

①:用戶名長度不能超過12;

②:只能有一個@符號;(沒有或者多個@都算錯)

③:@符號不能出現在第一個或者最後一個位置;

④:@必須出現在.前面;

⑤:email結尾必須以.com或者.cn結尾。

當這幾點都考慮好之後,函數基本就寫好了,然後我們在main方法中進行測試就行。

好了,第二期面試題分享就到這裏了,我們下期再見!

 

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