前言:目標(biāo)確定之后就要堅(jiān)持走下去,達(dá)到目標(biāo)的過(guò)程中,每一個(gè)困難都會(huì)淘汰一批人,克服不了自己也會(huì)淘汰,然后又換目標(biāo),發(fā)現(xiàn)干一段時(shí)間又有困難,困難不克服永遠(yuǎn)沒(méi)法成功!內(nèi)部類
定義在一個(gè)類當(dāng)中的類被稱為內(nèi)部類為什么要使用內(nèi)部類: 內(nèi)部類是共享數(shù)據(jù)最最簡(jiǎn)單的方式之一 *:內(nèi)部類也是類內(nèi)部類的分類:
成員內(nèi)部類,靜態(tài)內(nèi)部類,局部?jī)?nèi)部類,匿名內(nèi)部類成員內(nèi)部類:
成員內(nèi)部類共享外部類的所有[靜態(tài)+非靜態(tài)]成員[屬性+方法] 如何創(chuàng)建對(duì)象呢? Outer.Inner in = new Outer().new Inner(); #:成員內(nèi)部類與外部類的關(guān)系 就像蛔蟲(chóng)與牛的關(guān)系 *:相當(dāng)于孫悟空變成蒼蠅飛到妖怪的肚子里,妖怪的心肝脾肺腎都能被孫悟空訪問(wèn)到,妖怪就是外部類,孫悟空相當(dāng)于內(nèi)部類------public class Test01 { public static void main(String[] args){ Outer.Inner in = new Outer().new Inner(); in.test(); /* 10 20 30 Outer類的show()方法 */ }}class Outer{ int a = 10; static int b = 20; public void show(){ System.out.PRintln("Outer類的show()方法"); } class Inner{ int c = 30; public void test(){ System.out.println(a); System.out.println(b); System.out.println(c); show(); } }}------靜態(tài)內(nèi)部類
靜態(tài)內(nèi)部類共享外部類的靜態(tài)成員 如何創(chuàng)建對(duì)象? Outer.Inner in = new Outer.Inner(); #:靜態(tài)內(nèi)部類與外部類的關(guān)系,就像CPU與電腦 #:靜態(tài)內(nèi)部類只能訪問(wèn)外部類的靜態(tài)成員,但這不是目的,因?yàn)槠渌惗伎梢? 通過(guò)類名.訪問(wèn)外部類的靜態(tài)成員。靜態(tài)內(nèi)部類不是用來(lái)共享數(shù)據(jù)的,而是表示內(nèi)部類與 外部類有特定關(guān)系的,比如電腦與CPU------public class Test02 { public static void main(String[] args){ Outer.Inner in = new Outer.Inner(); in.test(); }}class Outer{ int a = 3; static int b = 9 ; static class Inner{ int x = 7; static int y = 9; public void test(){ System.out.println(a);//無(wú)法從靜態(tài)上下文中引用非靜態(tài) 變量 a System.out.println(b);//true System.out.println(x);//true System.out.println(y);//true } }}------局部?jī)?nèi)部類:
局部?jī)?nèi)部類共享外部類的成員取決于所在方法是不是靜態(tài)修飾 如果不是靜態(tài),則能夠共享所有成員 如果是靜態(tài),則只能共享靜態(tài)成員 另外還能訪問(wèn)其所在方法中final修飾的局部變量 *:JDK8開(kāi)始可以不加final,但是也必須是最終變量(不能修改) 如何創(chuàng)建對(duì)象呢? Inner in = new Inner(); *:注意必須在定義完成后,所在方法結(jié)束前![局部] *:注意局部?jī)?nèi)部類及局部變量都不能用static修飾 static為什么不能修飾局部變量? static修飾的變量要求當(dāng)類第一次被加載的時(shí)候 內(nèi)存空間里面就要有他 但是局部變量是當(dāng)所在的方法調(diào)用的時(shí)候 內(nèi)存空間才會(huì)有這個(gè)變量 類的加載永遠(yuǎn)再前面 方法的調(diào)用永遠(yuǎn)再后面 著兩個(gè)時(shí)間點(diǎn) 趕不上一起 于是static不能修飾局部變量------public class Test03 { public static void main(String[] args){ Outer out = new Outer(); out.show(30); }}class Outer{ int a = 10; static int b = 20; public void show(int c){ static int d = 40; class Inner{ int x = 50; public void test(){ System.out.println(a);//10 System.out.println(b);//20 System.out.println(c);//30 System.out.println(d);//40 System.out.println(x);//50 } } Inner in = new Inner(); in.test(); }}------public class Test03 { public static void main(String[] args){ Outer out = new Outer(); out.show(30); }}class Outer{ int a = 10; static int b = 20; public static void show(int c){ int d = 40; class Inner{ int x = 50; public void test(){ System.out.println(a);//無(wú)法從靜態(tài)上下文中引用非靜態(tài) 變量 a System.out.println(b);//20 System.out.println(c);//30 System.out.println(d);//40 System.out.println(x);//50 } } Inner in = new Inner(); in.test(); }}------匿名內(nèi)部類:
*:假如我們生個(gè)孩子就是為了賣錢的,事實(shí)上就不用給孩子起名字了 *:在某些時(shí)候我們?nèi)フ腋改傅呐笥艳k事,此時(shí)我們的名字根本就不重要,人家只關(guān)心你父母是誰(shuí), 你叫什么名字并沒(méi)有誰(shuí)在意(匿名內(nèi)部類當(dāng)成參數(shù)傳遞) 如何創(chuàng)建匿名內(nèi)部類對(duì)象? 父類類型 對(duì)象名字 = new 父類/接口(可能會(huì)傳參){ 完成方法實(shí)現(xiàn)或者方法覆蓋; }; 匿名內(nèi)部類能夠共享什么取決于定義它的位置,它能夠等價(jià)于上述三種的任何一種~------public class Test04 { public static void main(String[] args){ Set<Integer> set = new TreeSet<>(new Comparator<Integer>(){ @Override public int compare(Integer i1,Integer i2){ return i1 - i2; } }); Collections.addAll(set,44,33,66,77,55); System.out.println(set);//[33, 44, 55, 66, 77] }}/*class QQB implements Comparator<Integer>{ @Override public int compare(Integer i1 , Integer i2){ return i1 = i2; }}*/------public class Test05 { public static void main(String[] args){ Teacher tea = new Teacher(); tea.eat();//老師吃食物 Person stu = new Person("陳浩南",20){ @Override public void eat(){ System.out.println("學(xué)生吃扇貝"); } }; stu.eat();//學(xué)生吃扇貝 }}abstract class Person{ String name; int age; public Person(String name,int age){ this.name = name; this.age = age; } public abstract void eat();}class Teacher extends Person{ public Teacher(){ super("孔子",2000); } @Override public void eat(){ System.out.println("老師吃食物"); }}------共享數(shù)據(jù)的三種方法:
1.多個(gè)類共享一個(gè)類的靜態(tài)成員,即使用靜態(tài)變量完成數(shù)據(jù)的共享~------public class Test06 { public static void main(String[] args){ 呂布 lxb = new 呂布(); 董卓 dxz = new 董卓(); lxb.play();//呂小布play貂蟬 dxz.play();//董小卓play貂蟬 }}class 漱芳齋{ static Object 貂蟬 = new Object(){ @Override public String toString(){ return "貂蟬"; } };}class 呂布{ public void play(){ System.out.println("呂小布play"+漱芳齋.貂蟬); }}class 董卓{ public void play(){ System.out.println("董小卓paly"+漱芳齋.貂蟬); }}------ 2.使用參數(shù)傳遞完成共享------public class Test07 { public static void main(String[] args){ Object 貂蟬 = new Object(){ @Override public String toString(){ return "貂蟬"; } }; 呂布 lxb = new 呂布(貂蟬); 董卓 dxz = new 董卓(貂蟬); lxb.play();//呂小布play貂蟬 dxz.play();//董小卓play貂蟬 }}class 呂布{ Object obj; public 呂布(Object obj){ this.obj = obj; } public void play(){ System.out.println("呂小布play"+obj); }}class 董卓{ Object obj; public 董卓(Object obj){ this.obj = obj; } public void play(){ System.out.println("董小卓play" + obj); }}----- 3.使用內(nèi)部類完成數(shù)據(jù)共享-----public class Test08 { public static void main(String[] args){ 漱芳齋 sfz = new 漱芳齋(); 漱芳齋.呂布 lxb = sfz.new 呂布(); 漱芳齋.董卓 dxz = sfz.new 董卓(); lxb.play();//呂小布play貂蟬 dxz.play();//董小卓play貂蟬 }}class 漱芳齋{ Object 貂蟬 = new Object(){ @Override public String toString(){ return "貂蟬"; } }; class 呂布{ public void play(){ System.out.println("呂小布play"+貂蟬); } } class 董卓{ public void play(){ System.out.println("董小卓play"+貂蟬); } }}-----注意:傳參完成賦值的職業(yè)選手是setter方法,而不是構(gòu)造方法-----public class Test09 { public static void main(String[] args){ Teacher t = new Teacher(?); Student s = new Student(?);//這里怎么傳參初始化,此時(shí)就需要用setter來(lái)完成賦值 }}class Student{ Teacher tea; public Student(Teacher tea){ this.tea = tea; }}class Teacher{ Student stu; public Teacher(Student stu){ this.stu = stu; }}-----public class Test09 { public static void main(String[] args){ Student s = new Student(); Teacher t = new Teacher(); s.setTea(t); t.setStu(s); }}class Student{ Teacher tea; public void setTea(Teacher tea){ this.tea = tea; }}class Teacher{ Student stu; public void setStu(Student stu){ this.stu = stu; }}-----異常 Exception
例外->程序運(yùn)行過(guò)程中方出現(xiàn)的例外情況 Throwable[可拋出的]類 Error類 Exception類 [錯(cuò)誤] [異常] RuntimeException [運(yùn)行時(shí)異常] *:Error 和 Exception有什么區(qū)別? Error是指由于底層硬件或者系統(tǒng)原因?qū)е碌某绦騿T通過(guò)代碼無(wú)法解決的問(wèn)題,統(tǒng)稱為Error Exception是指程序運(yùn)行過(guò)程中出現(xiàn)了例外的情況 *:RuntimeException 和 Exception有什么區(qū)別? Exception是RuntimeException的父類 運(yùn)行時(shí)異常指的是在編譯時(shí)不需要給出處理方案 編譯就能通過(guò),問(wèn)題會(huì)在運(yùn)行時(shí)直接體現(xiàn) 非運(yùn)行時(shí)異常指的是在編譯時(shí)必須要給出問(wèn)題的處理方案,否則編譯無(wú)法通過(guò) *:常見(jiàn)的運(yùn)行時(shí)異常 ArithmeticException 算術(shù)異常 ArrayIndexOutOfBoundsException 數(shù)組索引值超出邊界異常 NegativeArraySizeException 負(fù)數(shù)數(shù)組大小異常 StringIndexOutOfBoundsException 字符串索引值超出邊界異常 NullPointerException 空指針異常 NumberFormatException 數(shù)字格式異常 ClassCastException 類造型異常 IndexOutOfBoundsException 索引值超出邊界異常 IllegalStateException 非法狀態(tài)異常 IllegalArgumentException 非法參數(shù)異常 ConcurrentModificationException 并發(fā)修改異常 *:常見(jiàn)的非運(yùn)行時(shí)異常 ClassNotFoundException FileNotFoundException NoSuchMethodException CloneNotSupportedException IOException------public class TestRuntimeException{ public static void main(String[] args){ //ConcurrentModificationException => 并發(fā)修改異常 //IllegalStateException => 非法狀態(tài)異常 List<Integer> list3 = new ArrayList<>(); Collections.addAll(list3,11,22,55,33,44); Iterator<Integer> car = list3.iterator(); car.next(); car.remove(); car.remove(); System.out.println(list3);//? //IndexOutOfBoundsException => 索引值超出邊界異常 List<Integer> list2 = new ArrayList<>(); System.out.println(list2.get(0)); //IllegalArgumentException => 非法的參數(shù)異常 List<Integer> list = new ArrayList<>(-8); //NumberFormatException => 數(shù)字格式異常 String str3 = "123a"; int num = Integer.parseInt(str3); //ClassCastException => 類造型異常 Object stu = new Student(); Cacti cc = (Cacti)stu; //StringIndexOutOfBoundsException => 字符串索引值超出邊界異常 String str2 = "123"; System.out.println(str2.charAt(5)); //NullPointerException => 空指針異常 String str = null; System.out.println(str.length());//? //ArrayIndexOutOfBoundsException => 數(shù)組索引值超出邊界異常 => 下標(biāo)越界 int[] data2 = new int[]{1,2,3}; System.out.println(data2[3]); //NegativeArraySizeException => 負(fù)的數(shù)組大小異常 int[] data1 = new int[-3]; //ArithmeticException => 算術(shù)異常 System.out.println(5.0 / 0); }}class Student{}//學(xué)生class Cacti{}//仙人掌------為什么要處理異常? a> 非運(yùn)行時(shí)異常如果不去處理,連編譯都無(wú)法通過(guò) b> 一旦程序出現(xiàn)異常,程序會(huì)直接中斷結(jié)束,不能繼續(xù)之后如何處理異常呢? 1.拋還上級(jí) throws 本方法當(dāng)中出現(xiàn)指定種類的異常 本方法不作處理,拋還給調(diào)用的上級(jí)方法當(dāng)中進(jìn)行處理 2.自行處理 try catch finally try{ 可能出現(xiàn)異常的語(yǔ)句;//一條語(yǔ)句可以出現(xiàn)多個(gè)異常,但是這多個(gè)異常也是細(xì)分下來(lái)一個(gè)操作拋出一個(gè)異常 }catch(要捕獲的異常種類 異常代號(hào)){ //可以什么都不做,無(wú)視 //1.簡(jiǎn)明扼要 System.out.println(異常代號(hào).getMessage()); //2.非常詳細(xì) e.printStackTrace();//看異常信息的時(shí)候從上往下找到第一個(gè)你寫的類 }finally{ 無(wú)論是否出現(xiàn)異常,最終都要執(zhí)行的操作 通常是釋放關(guān)閉資源的操作; *:這里不應(yīng)該出現(xiàn)return 和 throw *:System.exit(0);退出虛擬機(jī),以后代碼都不執(zhí)行了 } 注意: try{ return 5/0; }catch(Exception e){ return 10; }finally{ System.out.println(“我很帥”); } 5/0運(yùn)行后會(huì)出現(xiàn)異常,然后執(zhí)行catch分支,catch分支是return,則先不執(zhí)行,去執(zhí)行finally語(yǔ)句, 執(zhí)行完回到catch,return語(yǔ)句返回;如果try沒(méi)捕獲到異常,則return之前先去執(zhí)行finally然后回到try語(yǔ)句塊執(zhí)行return語(yǔ)句 *:一個(gè)try可以跟著多個(gè)catch,但是必須由小到大(最多并列)的范圍 *:JDK7.0開(kāi)始,我們可以在一個(gè)catch用|連接多個(gè)不同種類異常throw 和 throws的區(qū)別: throw 用在方法體當(dāng)中,在沒(méi)有異常出現(xiàn)的情況下主動(dòng)制造異常出現(xiàn)的場(chǎng)景 throws 用在方法簽名的最后,表示本方法當(dāng)中出現(xiàn)指定的異常,本方法不作處理,拋還給調(diào)用的上級(jí)(方法)處理-----public class Test08{ public static void main(String[] args){ test(0); } public static int test(int x){ try{ return 5 / x; }catch(Exception e){ return 0; }finally{ System.out.println("EtoakViva"); } }}-----//finally當(dāng)中永遠(yuǎn)不應(yīng)當(dāng)出現(xiàn)return語(yǔ)句~public class Test9{ public static void main(String[] args){ System.out.println(test(100)); System.out.println(test(50)); System.out.println(test(0)); System.out.println(test(50)); System.out.println(test(100)); } public static int test(int x){ try{ return 100 / x; }catch(Exception e){ System.out.println("吖 出事了吖~"); return 0; }finally{ return 7777; } }}擴(kuò)展知識(shí):*********
1:當(dāng)一個(gè)成員變量通過(guò)調(diào)用一個(gè)有一場(chǎng)聲明的方法來(lái)賦值的時(shí)候, 我們可以借助初始化塊來(lái)完成異常處理-------public class Test01 { public static void main(String[] args)throws Exception{ A a = new A(); System.out.println(a.a); }}class A{ /*第一種,通過(guò)構(gòu)造方法初始化成員變量,然后構(gòu)造方法拋出異常 int a ; public A()throws Exception { a = get(); } */ //第二種:通過(guò)代碼塊進(jìn)行try{}catch(){}處理 int a; { try { a = get(); } catch (Exception e) { e.printStackTrace(); } } public static int get() throws Exception{ int lucky = (int)(Math.random()*10); if(lucky == 2 || lucky == 4){ throw new Exception("NotJiLiException"); } return lucky; }}-----2:當(dāng)我們執(zhí)行多個(gè)關(guān)閉釋放資源時(shí),如果一個(gè)出現(xiàn)異常,其他關(guān)閉操作無(wú)法執(zhí)行,此時(shí) 我們可以挨個(gè)try{}catch(){},或者foreach循環(huán)try{}catch(){},循環(huán)操作之前必須要保證 多個(gè)操作屬于同一種類型或者實(shí)現(xiàn)同一個(gè)接口,這樣可以使用多態(tài)解耦特點(diǎn)來(lái)實(shí)現(xiàn)-----public class Test10 { public static void main(String[] args) { SLT slt1 = new SLT(); SLT slt2 = new SLT(); SLT slt3 = new SLT(); /*try{ slt1.close(); }catch(Exception e){ e.printStackTrace(); } try{ slt2.close(); }catch(Exception e){ e.printStackTrace(); } try{ slt3.close(); }catch(Exception e){ e.printStackTrace(); }*/ //這種方式有個(gè)弊端,假如第一個(gè)catch中有return語(yǔ)句,那么剩下兩個(gè)try catch不會(huì)執(zhí)行,所以應(yīng)該如下表示 /*try{ slt1.close(); }catch(Exception e){ e.printStackTrace(); }finally{ try{ slt2.close(); }catch(Exception e){ e.printStackTrace(); }finally{ try{ slt3.close(); }catch(Exception e){ e.printStackTrace(); } } }*/ //這種代碼層級(jí)太多,可以寫一個(gè)closeAll()方法 closeAll(slt3, slt2, slt1); } public static void closeAll(SLT... slt){ for(SLT s : slt){ try{ s.close(); }catch(Exception e){ e.printStackTrace(); } } }}class SLT{ public void close()throws Exception{ int lucky = (int)(Math.random()*2); if(lucky == 0) throw new Exception("水龍頭關(guān)閉異常!"); System.out.println("正常關(guān)閉水龍頭"); }}-----假如不是同一種類型,則可以讓不同種類的水龍頭實(shí)現(xiàn)相同的接口,代碼如下:-----public class Test11 { public static void main(String[] args){ SLTA slta = new SLTA(); SLTB sltb = new SLTB(); SLTC sltc = new SLTC(); closeAll(sltc,sltb,slta); } public static void closeAll(CloseableSLT... slt){ for(CloseableSLT s : slt){ try{ s.close(); }catch(Exception e){ e.printStackTrace(); } } }}interface CloseableSLT{ void close();}class SLTA implements CloseableSLT{ @Override public void close(){ int lucky = (int)(Math.random()*2); if(lucky == 0) throw new RuntimeException("水龍頭SLTA關(guān)閉異常!!!"); System.out.println("水龍頭SLTA正常關(guān)閉"); }}class SLTB implements CloseableSLT{ @Override public void close(){ int lucky = (int)(Math.random()*2); if(lucky == 0) throw new RuntimeException("水龍頭SLTB關(guān)閉異常!!!"); System.out.println("水龍頭SLTB正常關(guān)閉"); }}class SLTC implements CloseableSLT{ @Override public void close(){ int lucky = (int)(Math.random()*2); if(lucky == 0) throw new RuntimeException("水龍頭SLTC關(guān)閉異常!!!"); System.out.println("水龍頭SLTC正常關(guān)閉"); }}-----3:所有方法默認(rèn)拋出RuntimeException,子類覆蓋父類方法時(shí),表面上父類方法沒(méi)有拋出異常,子類拋出了多個(gè)RuntimeException但實(shí)際上都拋出RuntimeException。-----public class Test12 { public static void main(String[] args){ B b = new B(); b.test(); }}class A{ public void test(){ System.out.println("父類A中的test()方法"); }}class B extends A{ @Override public void test()throws NullPointerException,IllegalArgumentException{ System.out.println("子類B中的test()方法"); }}-----4:當(dāng)調(diào)用拋出異常的方法給局部變量賦值時(shí),可以將初始化語(yǔ)句放在try{}catch(){}外-----public class Test13 { public static void main(String[] args){ int x = 0;//局部變量沒(méi)有初始值,必須要保證在使用之前已經(jīng)賦值了 try{ x = get(); }catch(Exception e){ e.printStackTrace(); } System.out.println(x); } public static int get()throws Exception{ int lucky = (int)(Math.random()*2); if(lucky == 0) throw new Exception("有一定概率犧牲!!"); return lucky; }}-----5:討論:將來(lái)的將來(lái)是否可以用try catch取代傳統(tǒng)的分支結(jié)構(gòu),包括if else / switch case-----public class Test14 { public static void main(String[] args){ System.out.println(check("a1213131"));//false System.out.println(check("1213131"));//true System.out.println(check("-1"));//true } public static boolean check(String str){ /** * 要求,如果參數(shù)str是由全數(shù)字組成則方法返回true * 否則返回false */ try{ Integer.parseInt(str); return true; }catch(Exception e){ return false; } }}-----
|
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注