Java學習筆記-Day21 Java System類、Class類、內部類、異常處理

金海湖底有寶藏發表於2020-11-02



一、System類


System類(java.lang.System)包含幾個有用的類欄位和方法。 它不能被例項化。

1、System類提供的屬性


static PrintStream err :“標準”錯誤輸出流,輸出顏色為紅色的資料。

System.err.println("red information");

static PrintStream out :“標準”輸出流,輸出資料。

System.out.println("information");

static InputStream in :“標準”輸入流。

Scanner sc = new Scanner(System.in);

2、System類提供的靜態方法


static long currentTimeMillis() :返回當前時間(以毫秒為單位)。

	long l = System.currentTimeMillis();//1604325938003

static long nanoTime():以納秒為單位返回正在執行的Java虛擬機器的高解析度時間源的當前值。

	long l = System.nanoTime();//1311210526165100

static void exit(int status) :終止當前執行的Java虛擬機器。

	System.exit(0);

static void gc() :執行垃圾回收器。

	System.gc();

二、Class類


Class 類的例項表示正在執行的 Java 應用程式中的類和介面。

列舉是一種類,註釋是一種介面。每個陣列屬於被對映為 Class 物件的一個類,所有具有相同元素型別和維數的陣列都共享該 Class 物件。

Java 的基本資料型別(boolean、byte、char、short、int、long、float 和 double)和關鍵字 void 表示為 Class 物件。

Class 沒有公共構造方法。Class 物件是在載入類時由 Java 虛擬機器以及通過呼叫類載入器中的 defineClass 方法自動構造的。

1、獲取Class類的物件


(1)呼叫 Class類的靜態方法 forName,引數是 完整的包名+類名。

static 類<?> forName(String className) :返回與給定字串名稱的類或介面相關聯的 Class類的物件。

	Class c = Class.forName("day19.Apple");

(2)通過 物件.class,得到一個Class類的物件。

	Apple a = new Apple();
	Class c = a.class;

(3)通過 類.getClass(),得到一個Class類的物件。

	Class c = Apple.getClass();

2、例項化Class類表示的物件


newInstance() :建立由此Class類的物件表示的類的新例項。

	Object obj = c.newInstance();

3、某個物件是否屬於特定的類


通過使用關鍵字 instanceof 來判斷某個物件是否屬於特定的類。

	if(obj instanceof Apple) {
		Apple a = (Apple)obj;
	}

4、根據使用者的輸入來建立某個類的物件

		//根據使用者的輸入來建立某個類的物件
		Scanner sc = new Scanner(System.in);
		String name = sc.next();
		Class c = Class.forName(name);
		Object obj = c.newInstance();
		if(obj instanceof Apple) {
			Apple a = (Apple)obj;
			a.showInfo();
		}

三、內部類


內部類是在一個類的內部定義另一個類,內部類就成為外部類中的成員,訪問許可權修飾符可以是public、protected、default和private。

1、內部類的意義

(1)折中處理了類實現多繼承。

//可以看作 類D 繼承了 類A 和 類B
public class C extends A{
	public class D extends B{
		
		public void showA() {
			showA();
		}
		
		@Override
		public void showB() {
			super.showB();
		}
	}
}

class B {
	public void showB() {
		System.out.println("b");
	}
}

class A {
	public void showA() {
		System.out.println("a");
	}
}


(2)形成閉包( 外部類中無法直接訪問內部類中的成員,內部類中可以直接訪問外部類的成員)。

public class OuterClass {
	int i;
	public void show1() {
		System.out.println(i);
		//System.out.println(j); 不能呼叫InnerClass中的變數j
	}
	public class InnerClass{
		int j;
		public void show2() {
			System.out.println(i);//能呼叫InnerClass中的變數i
			System.out.println(j);
		}
	} 
}

2、內部類的分類

2.1、成員內部類


成員內部類是最普通的內部類。成員內部類是外部類的一個成員,可以無限制的訪問外部類的所有成員屬性和方法,包括 private 的。但是外部類要訪問內部類的成員屬性和方法則需要通過內部類例項來訪問。

2.1.1、定義成員內部類


成員內部類中不能存在任何static的變數和方法。

//外部類
class OuterClass {
	int i;
	public void show1() {
		System.out.println(i);
	}
	//成員內部類
	public class InnerClass{
		int j;
		public void show2() {
			System.out.println(i);
			System.out.println(j);
		}
	} 
}

2.1.2、建立成員內部類物件


成員內部類是依附於外部類的,只有先建立了外部類才能夠建立內部類。

(1)首先建立外部類物件。
(2)以 外部內.內部類 的形式進行宣告。
(2)以 外部內物件.new 內部類構造方法() 的方式建立物件。

	//建立外部類物件
	OuterClass o = new OuterClass();
	//外部類.內部類 物件名 = 外部類物件.new 內部類()
	OuterClass.InnerClass i = o.new InnerClass();

2.2、區域性內部類


區域性內部類定義在了方法的內部,只能在該方法和作用域中被使用,出了該方法和作用域就會失效。區域性內部類可以直接操作外部類的成員變數,但是對於方法的臨時變數(包括方法的引數,要求是常量才能操作)。

//外部類
public class OuterClass {
	int a = 1;
	public void show() {
		//區域性內部類
		class InnerClass{
			int b= 1;
			public void show() {
				System.out.println(a);
				System.out.println(b);
			}
		}
		//在方法體中建立區域性內部類物件
		InnerClass i = new InnerClass();
		i.show();
	}
}

2.3、靜態內部類


使用static修飾的內部類稱為靜態內部類。靜態內部類與非靜態內部類之間存在一個最大的區別,非靜態內部類在編譯完成之後會隱含地儲存著一個引用,該引用是指向建立它的外部類,但是靜態內部類卻沒有。沒有這個引用就意味著:

(1)它的建立是不需要依賴於外部類。
(2)它不能使用任何外部類的非static成員變數和方法。
(3)和成員內部類不同,static內部類能夠宣告static的成員。

2.3.1、定義靜態內部類

	//外部類
	public class OuterClass {
		static int a = 1;
		//靜態內部類
		static class InnerClass{
			int b= 1;
			public void show() {
				System.out.println(a);
				System.out.println(b);
			}
		}
	}

2.3.2、建立靜態內部類物件


靜態內部類建立物件時,不需要依賴外部類的物件。

	//外部類.內部類 物件名 = new 外部類.內部類的構造方法();
	OuterClass1.InnerClass1 i = new OuterClass1.InnerClass1();

2.4、匿名內部類


(1)匿名內部類是指不存在名字的內部類。

(2)匿名內部類必須繼承一個父類或實現一個介面。

(3)匿名內部類沒有構造方法,匿名內部類沒有顯式類名。

(4)匿名內部類要想完成一些初始化工作可以交由靜態初始化或構造程式碼塊來完成。

(5)匿名內部類對類的成員、方法的臨時變數的訪問規則和具備名字的內部類保持一致。

2.4.1、定義匿名內部類


在這裡插入圖片描述

//外部類
public class TestOuterClass3 {
	//匿名內部類
	public OuterInterface i = new OuterInterface() {
		int a = 123;
		@Override
		public void show() {
			System.out.println(a);
		}
	};

	public static void main(String[] args) {
		TestOuterClass3 t = new TestOuterClass3();
		t.i.show();
	}
}

interface OuterInterface {
	public void show();
}

3、內部類編譯後的位元組碼檔案


內部類是個編譯時的概念,一旦編譯成功後,它就與外部類屬於兩個完全不同的類(它們之間還是有聯絡的)。

//外部類
public class OuterClass{
	//內部類
    class InnerClass {
        void show(){
			System.out.println("InnerClass");
		};
    }
	//介面
	interface OuterInterface {
		public void show();
	}
	//匿名內部類
	public OuterInterface i = new OuterInterface() {
		int a = 123;
		@Override
		public void show() {
			System.out.println("OuterInterface");
		}
	};
	
	public static void main(String[] args) {
		OuterClass c = new OuterClass();
	}
}

在編譯成功後,會出現這樣class檔案:

外部類OuterClass: OuterClass.class
內部類InnerClass: OuterClass$InnerClass.class
介面OuterInterface:OuterClass$OuterInterface.class
匿名內部類:OuterClass$1.class

四、異常處理


異常是指程式執行時發生的不正常事件,會影響後續程式碼的執行。異常能被程式處理,保證程式繼續執行。

1、異常處理語法

1.1、try-catch


主動處理,出現在方法內部。
在這裡插入圖片描述

		try {
			int[] i = {1,2,3};
			i[4]=10;
		} catch (Exception e) {
			System.out.println("陣列下標越界異常");
			e.printStackTrace();
		}

1.2、try-catch-finally


主動處理,出現在方法內部。
在這裡插入圖片描述

		try {
			int[] i = {1,2,3};
			i[4]=10;
		} catch (Exception e) {
			System.out.println("陣列下標越界異常");
			e.printStackTrace();
		}finally{
			System.out.println("finally");
		}

1.3、throws


向上丟擲異常,誰呼叫就拋給誰。在方法名的後面新增 throws 異常名

	public static void main(String[] args) throws ParseException {	
			new SimpleDateFormat("yyyy-MM").parse("2019-12");
	}

五、Synchronized關鍵字


可以保證在同一時刻,只有一個執行緒可以執行某個方法或某個程式碼塊,同時可以保證一個執行緒的變化可見。

相關文章