更新時間:2020-02-25 09:14:25 來源:動力節(jié)點 瀏覽2131次
Java的知識點其實非常多,并且有些知識點比較難以理解,有時候我們自以為理解了某些內(nèi)容,其實可能只是停留在表面上,沒有理解其底層實現(xiàn)原理。
面向?qū)ο?/span>三大特性
繼承:一般類只能單繼承,內(nèi)部類實現(xiàn)多繼承,接口可以多繼承封裝:訪問權(quán)限控制public>protected>包>private內(nèi)部類也是一種封裝多態(tài):編譯時多態(tài),體現(xiàn)在向上轉(zhuǎn)型和向下轉(zhuǎn)型,通過引用類型判斷調(diào)用哪個方法(靜態(tài)分派)。運行時多態(tài),體現(xiàn)在同名函數(shù)通過不同參數(shù)實現(xiàn)多種方法(動態(tài)分派)。
基本數(shù)據(jù)類型
1基本類型位數(shù),自動裝箱,常量池2例如byte類型是1byte也就是8位,可以表示的數(shù)字是-128到127,因為還有一個0,加起來一共是256,也就是2的八次方。32位和64位機器的int是4個字節(jié)也就是32位,char是1個字節(jié)就是8位,float是4個字節(jié),double是8個字節(jié),long是8個字節(jié)。3基本數(shù)據(jù)類型的包裝類只在數(shù)字范圍-128到127中用到常量池,會自動拆箱裝箱,其余數(shù)字范圍的包裝類則會新建實例
String及包裝類
1String類型是final類型,在堆中分配空間后內(nèi)存地址不可變。2底層是final修飾的char[]數(shù)組,數(shù)組的內(nèi)存地址同樣不可變。但實際上可以通過修改char[n]='a'來進行修改,不會改變String實例的內(nèi)存值,不過在jdk中,用戶無法直接獲取char[],也沒有方法能操作該數(shù)組。所以String類型的不可變實際上也是理論上的不可變。所以我們在分配String對象以后,如果將其="abc",那也只是改變了引用的指向,實際上沒有改變原來的對象。3StringBuffer和StringBuilder底層是可變的char[]數(shù)組,繼承父類AbstractStringBuilder的各種成員和方法,實際上的操作都是由父類方法來完成的。
final關鍵字
1final修飾基本數(shù)據(jù)類型保證不可變2final修飾引用保證引用不能指向別的對象,否則會報錯。3final修飾類,類的實例分配空間后地址不可變,子類不能重寫所有父類方法。因此在cglib動態(tài)代理中,不能為一個類的final修飾的函數(shù)做代理,因為cglib要將被代理的類設置為父類,然后再生成字節(jié)碼。final修飾方法,子類不能重寫該方法。
抽象類和接口
1抽象類可以有方法實現(xiàn)。抽象類可以有非final成員變量。抽象方法要用abstract修飾。抽象類可以有構(gòu)造方法,但是只能由子類進行實例化。2接口可以用extends加多個接口實現(xiàn)多繼承。接口只能有publicfinal類型的成員變量。接口只能有抽象方法,不能有方法體、接口不能實例化,但是可以作為引用類型。
代碼塊和加載順序
假設該類是第一次進行實例化。那么有如下加載順序靜態(tài)總是比非靜態(tài)優(yōu)先,從早到晚的順序是:1靜態(tài)代碼塊和靜態(tài)成員變量的順序根據(jù)代碼位置前后來決定。2代碼塊和成員變量的順序也根據(jù)代碼位置來決定3最后才調(diào)用構(gòu)造方法構(gòu)造方法
包、內(nèi)部類、外部類
1Java項目一般從src目錄開始有com...A.java這樣的目錄結(jié)構(gòu)。這就是包結(jié)構(gòu)。所以一般編譯后的結(jié)構(gòu)是跟包結(jié)構(gòu)一模一樣的,這樣的結(jié)構(gòu)保證了import時能找到正確的class引用包訪問權(quán)限就是指同包下的類可見。import一般加上全路徑,并且使用.*時只包含當前目錄的所有類文件,不包括子目錄。2外部類只有public和default兩種修飾,要么全局可訪問,要么包內(nèi)可訪問。3內(nèi)部類可以有全部訪問權(quán)限,因為它的概念就是一個成員變量,所以訪問權(quán)限設置與一般的成員變量相同。非靜態(tài)內(nèi)部類是外部類的一個成員變量,只跟外部類的實例有關。靜態(tài)內(nèi)部類是獨立于外部類存在的一個類,與外部類實例無關,可以通過外部類.內(nèi)部類直接獲取Class類型。
異常
1異常體系的最上層是Throwable類子類有Error和ExceptionException的子類又有RuntimeException和其他具體的可檢查異常。2Error是jvm完全無法處理的系統(tǒng)錯誤,只能終止運行。運行時異常指的是編譯正確但運行錯誤的異常,如數(shù)組越界異常,一般是人為失誤導致的,這種異常不用trycatch,而是需要程序員自己檢查。可檢查異常一般是jvm處理不了的一些異常,但是又經(jīng)常會發(fā)生,比如Ioexception,Sqlexception等,是外部實現(xiàn)帶來的異常。3多線程的異常流程是獨立的,互不影響。大型模塊的子模塊異常一般需要重新封裝成外部異常再次拋出,否則只能看到最外層異常信息,難以進行調(diào)試。日志框架是異常報告的最好幫手,log4j,slf4j中,在工作中必不可少。
泛型
1Java中的泛型是偽泛型,只在編譯期生效,運行期自動進行泛型擦除,將泛型替換為實際上傳入的類型。泛型類用classA{}2這樣的形式表示,里面的方法和成員變量都可以用T來表示類型。泛型接口也是類似的,不過泛型類實現(xiàn)泛型接口時可以選擇注入實際類型或者是繼續(xù)使用泛型。3泛型方法可以自帶泛型比如void
Class類和Object類
1Java反射的基礎是Class類,該類封裝所有其他類的類型信息,并且在每個類加載后在堆區(qū)生成每個類的一個Class<類名>實例,用于該類的實例化。2Java中可以通過多種方式獲取Class類型,比如A.class,newA().getClass()方法以及Class.forName("com.?.?.A")方法。3Object是所有類的父類,有著自己的一些私有方法,以及被所有類繼承的9大方法。知乎上有人討論Object和Class類型誰先加載誰后加載,因為每個類都要繼承Object,但是又得先被加載到堆區(qū),事實上,這個問題在JVM初始化時就解決了,沒必要多想。
javac和java
1javac是編譯一個java文件的基本命令,通過不同參數(shù)可以完成各種配置,比如導入其他類,指定編譯路徑等。2java是執(zhí)行一個java文件的基本命令,通過參數(shù)配置可以以不同方式執(zhí)行一個java程序或者是一個jar包。3javap是一個class文件的反編譯程序,可以獲取class文件的反編譯結(jié)果,甚至是jvm執(zhí)行程序的每一步代碼實現(xiàn)。
反射
1Java反射包reflection提供對Class,Method,field,constructor1等信息的封裝類型。2通過這些api可以輕易獲得一個類的各種信息并且可以進行實例化,方法調(diào)用等。類中的private參數(shù)可以通過setaccessible方法強制獲取。3反射的作用可謂是博大精深,JDK動態(tài)代理生成代理類的字節(jié)碼后,首先把這個類通過defineclass定義成一個類,然后用class.for(name)會把該類加載到jvm,之后我們就可以通過,A.class.GetMethod()獲取其方法,然后通過invoke調(diào)用其方法,在調(diào)用這個方法時,實際上會通過被代理類的引用再去調(diào)用原方法。
枚舉類
1枚舉類繼承Enum并且每個枚舉類的實例都是唯一的。2枚舉類可以用于封裝一組常量,取值從這組常量中取,比如一周的七天,一年的十二個月。3枚舉類的底層實現(xiàn)其實是語法糖,每個實例可以被轉(zhuǎn)化成內(nèi)部類。并且使用靜態(tài)代碼塊進行初始化,同時保證內(nèi)部成員變量不可變。
序列化
1序列化的類要實現(xiàn)serializable接口transient修飾符可以保證某個成員變量不被序列化readObject和writeOject來實現(xiàn)實例的寫入和讀取。2事實上,一些擁有數(shù)組變量的類都會把數(shù)組設為transient修飾,這樣的話不會對整個數(shù)組進行序列化,而是利用專門的方法將有數(shù)據(jù)的數(shù)組范圍進行序列化,以便節(jié)省空間。
動態(tài)代理
1jdk自帶的動態(tài)代理可以代理一個已經(jīng)實現(xiàn)接口的類。2cglib代理可以代理一個普通的類。3動態(tài)代理的基本實現(xiàn)原理都是通過字節(jié)碼框架動態(tài)生成字節(jié)碼,并且在用defineclass加載類后,獲取代理類的實例。一般需要實現(xiàn)一個代理處理器,用來處理被代理類的前置操作和后置操作。在JDK動態(tài)代理中,這個類叫做invocationHandler。4JDK動態(tài)代理首先獲取被代理類的方法,并且只獲取在接口中聲明的方法,生成代理類的字節(jié)碼后,首先把這個類通過defineclass定義成一個類,然后把該類加載到jvm,之后我們就可以通過,A.class.GetMethod()獲取其方法,然后通過invoke調(diào)用其方法,在調(diào)用這個方法時,實際上會通過被代理類的引用再去調(diào)用原方法。5而對于cglib動態(tài)代理,一般會把被代理類設為代理類的父類,然后獲取被代理類中所有非final的方法,通過asm字節(jié)碼框架生成代理類的字節(jié)碼,這個代理類很神奇,他會保留原來的方法以及代理后的方法,通過方法數(shù)組的形式保存。cglib的動態(tài)代理需要實現(xiàn)一個enhancer和一個interceptor,在interceptor中配置我們需要的代理內(nèi)容。如果沒有配置interceptor,那么代理類會調(diào)用被代理類自己的方法,如果配置了interceptor,則會使用代理類修飾過的方法。
這里先不講juc包里的多線程類。juc相關內(nèi)容會在Java并發(fā)專題講解。1線程的實現(xiàn)可以通過繼承Thread類和實現(xiàn)Runable接口也可以使用線程池。callable配合future可以實現(xiàn)線程中的數(shù)據(jù)獲取。2Java中的線程有7種狀態(tài),newrunablerunningblockedwaitingtimewaitingterminateblocked是線程等待其他線程鎖釋放。waiting是wait以后線程無限等待其他線程使用notify喚醒timewating是有限時間地等待被喚醒,也可能是sleep固定時間。3Thread的join是實例方法,比如a.join(b),則說明a線程要等b線程運行完才會運行。4o.wait方法會讓持有該對象o的線程釋放鎖并且進入阻塞狀態(tài),notify則是持有o鎖對象的線程通知其他等待鎖的線程獲取鎖。notify方法并不會釋放鎖。注意這兩個方法都只能在synchronized同步方法或同步塊里使用。5synchronized方法底層使用系統(tǒng)調(diào)用的mutex鎖,開銷較大,jvm會為每個鎖對象維護一個等待隊列,讓等待該對象鎖的線程在這個隊列中等待。當線程獲取不到鎖時則讓線程阻塞,而其他檢查notify以后則會通知任意一個線程,所以這個鎖時非公平鎖。6Thread.sleep(),Thread.interrupt()等方法都是類方法,表示當前調(diào)用該方法的線程的操作。一個線程實例連續(xù)start兩次會拋異常,這是因為線程start后會設置標識,如果再次start則判斷為錯誤。
IO流
1IO流也是Java中比較重要的一塊,Java中主要有字節(jié)流,字符流,文件等。其中文件也是通過流的方式打開,讀取和寫入的。2IO流的很多接口都使用了裝飾者模式,即將原類型通過傳入裝飾類構(gòu)造函數(shù)的方式,增強原類型,以此獲得像帶有緩沖區(qū)的字節(jié)流,或者將字節(jié)流封裝成字符流等等,其中需要注意的是編碼問題,后者打印出來的結(jié)果可能是亂碼哦。3IO流與網(wǎng)絡編程息息相關,一個socket接入后,我們可以獲取它的輸入流和輸出流,以獲取TCP數(shù)據(jù)包的內(nèi)容,并且可以往數(shù)據(jù)報里寫入內(nèi)容,因為TCP協(xié)議也是按照流的方式進行傳輸?shù)模瑢嶋H上TCP會將這些數(shù)據(jù)進行分包處理,并且通過差錯檢驗,超時重傳,滑動窗口協(xié)議等方式,保證了TCP數(shù)據(jù)包的高效和可靠傳輸。
網(wǎng)絡編程
承接IO流的內(nèi)容1IO流與網(wǎng)絡編程息息相關,一個socket接入后,我們可以獲取它的輸入流和輸出流,以獲取TCP數(shù)據(jù)包的內(nèi)容,并且可以往數(shù)據(jù)報里寫入內(nèi)容,因為TCP協(xié)議也是按照流的方式進行傳輸?shù)模瑢嶋H上TCP會將這些數(shù)據(jù)進行分包處理,并且通過差錯檢驗,超時重傳,滑動窗口協(xié)議等方式,保證了TCP數(shù)據(jù)包的高效和可靠傳輸。2除了使用socket來獲取TCP數(shù)據(jù)包外,還可以使用UDP的DatagramPacket來封裝UDP數(shù)據(jù)包,因為UDP數(shù)據(jù)包的大小是確定的,所以不是使用流方式處理,而是需要事先定義他的長度,源端口和目標端口等信息。3為了方便網(wǎng)絡編程,Java提供了一系列類型來支持網(wǎng)絡編程的api,比如URL類,InetAddress類等。后續(xù)文章會帶來NIO相關的內(nèi)容,敬請期待。
Java8
1接口中的默認方法,接口終于可以有方法實現(xiàn)了,使用注解即可標識出默認方法。2lambda表達式實現(xiàn)了函數(shù)式編程,通過注解可以聲明一個函數(shù)式接口,該接口中只能有一個方法,這個方法正是使用lambda表達式時會調(diào)用到的接口。3Option類實現(xiàn)了非空檢驗4各種api的更新,包括chm,hashmap的實現(xiàn)等5Stream流概念,實現(xiàn)了集合類的流式訪問,可以基于此使用map和reduce并行計算。
以上就是動力節(jié)點Java培訓機構(gòu)小編介紹的“最新Javase基礎視頻及Java基礎知識總結(jié)”的內(nèi)容,希望對大家有幫助,如有疑問,請在線咨詢,有專業(yè)老師隨時為你服務。