J2SE基礎(chǔ)~4
開心一刻: 一輛QQ和一輛瑪莎拉蒂追尾,QQ司機(jī)大怒:窮逼。你特么開輛破車得瑟啥?所有路人都一愣,不知道QQ司機(jī)是哪來的勇氣,這時(shí),只見馬化騰從QQ里出來... ...
下面正式進(jìn)入干貨區(qū),喜歡的話、雙擊、評(píng)論、轉(zhuǎn)發(fā),動(dòng)一動(dòng)你的小手讓更多的人知道!關(guān)注帥比~楊
反射的作用與原理。
泛型常用特點(diǎn)。
解析XML的幾種方式的原理與特點(diǎn):DOM、SAX、PULL。
Java與C++對(duì)比。
Java1.7與1.8新特性。
設(shè)計(jì)模式:?jiǎn)卫⒐S、適配器、責(zé)任鏈、觀察者等等。
JNI的使用。
1. 反射的作用與原理。
反射的概念:所謂的反射就是java語言在運(yùn)行時(shí)擁有一項(xiàng)自觀的能力,反射使您的程序代碼能夠得到裝載到JVM中的類的內(nèi)部信息,允許您執(zhí)行程序時(shí)才得到需要類的內(nèi)部信息,而不是在編寫代碼的時(shí)候就必須要知道所需類的內(nèi)部信息,這使反射成為構(gòu)建靈活的應(yīng)用的主要工具。 反射的常用類和函數(shù):Java反射機(jī)制的實(shí)現(xiàn)要借助于4個(gè)類:Class,Constructor,F(xiàn)ield,Method;其中class代表的是類對(duì)象,Constructor-類的構(gòu)造器對(duì)象,F(xiàn)ield-類的屬性對(duì)象,Method-類的方法對(duì)象,通過這四個(gè)對(duì)象我們可以粗略的看到一個(gè)類的各個(gè)組成部分。其中最核心的就是Class類,它是實(shí)現(xiàn)反射的基礎(chǔ)。
** 反射的用途: **
1> 在運(yùn)行時(shí)獲取任意對(duì)象所屬的類
2> 在運(yùn)行時(shí)構(gòu)造任意類的對(duì)象
3> 在運(yùn)行時(shí)獲取任意類所具有的成員變量和方法
核心方法:
成員屬性(Field):
getFields():獲得類的public類型的屬性。
getDeclaredFields():獲得類的所有屬性。
getField(String name)getDeclaredField(String name):獲取類的特定屬性成員方法(Method):
getMethods():獲得類的public類型的方法。
getDeclaredMethods():獲得類的所有方法。
getMethod(String name, Class[] parameterTypes):獲得類的特定方法
getDeclaredMethod(String name, Class[] parameterTypes):獲得類的特定方法構(gòu)造方法(Constructor):
getConstructors():獲得類的public類型的構(gòu)造方法。
getDeclaredConstructors():獲得類的所有構(gòu)造方法。
getConstructor(Class[] parameterTypes):獲得類的特定構(gòu)造方法getDeclaredConstructor(Class[] params);獲得類的特定方法
2. 泛型常用特點(diǎn)
類型安全:泛 型的主要目標(biāo)是提高Java程序的類型安全。通過知道使用泛型定義的變量的類型限制,編譯器可以在一個(gè)高得多的程度上驗(yàn)證類型假設(shè)。沒有泛型,這些假設(shè)就 只存在于程序員的腦海中。Java程序中的一種流行技術(shù)是定義這樣的集合,即它的元素或鍵是功能類型的,比如“_列表”。通過在變量聲明中捕獲這一附加的 類型信息,泛型允許編譯器實(shí)施這些附加的約束,類型錯(cuò)誤現(xiàn)在就可以在編譯時(shí)被捕獲了,而不是在運(yùn)行時(shí)才來進(jìn)行檢測(cè)操作。
消除強(qiáng)制類型轉(zhuǎn)換:泛型的一個(gè)附帶的好處是,消除源代碼中的許多強(qiáng)制類型轉(zhuǎn)換,這使得代碼更加可讀,而且減少了出錯(cuò)的機(jī)會(huì)。比較兩段代碼:
不使用泛型的代碼段:
List li = new ArrayList();
li.add(new Integer(3));
Integer i = (Integer)li.get(0);
使用泛型:
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(3));
Integer i = li.get(0);
3. 解析XML的幾種方式的原理與特點(diǎn):DOM、SAX、PULL。
---------------------------------------------DOM解析xml------------------------------------------
1> 整個(gè)文檔樹在內(nèi)存中,便于操作;支持刪除、修改、重新排列等多種功能
2> 通過樹形結(jié)構(gòu)存取xml文檔
3> 可以在樹的某個(gè)節(jié)點(diǎn)上向前或向后移動(dòng)
缺點(diǎn):
將整個(gè)文檔調(diào)入內(nèi)存(包括無用的節(jié)點(diǎn)),浪費(fèi)時(shí)間和空間
適用場(chǎng)合:
一旦解析了文檔還需多次訪問這些數(shù)據(jù);硬件資源充足(內(nèi)存,cpu)
---------------------------------------------PULL解析xml------------------------------------------
pull解析器是android內(nèi)置的解析器,解析原理與sax類似。它提供了類似的事件。如:開始元素和結(jié)束元素事件,使用parse.next()可以進(jìn)入下一個(gè)元素并觸發(fā)相應(yīng)的事件,事件將作為數(shù)值代碼被發(fā)送,因此可以使用一個(gè)switch對(duì)感興趣的事件進(jìn)行處理。當(dāng)元素開始解析時(shí),調(diào)用parser.nextText()方法獲取下一個(gè)Text類型節(jié)點(diǎn)的值。
pull與sax的不同之處如下:
1> pull讀取xml文件后觸發(fā)相應(yīng)的事件調(diào)用方法返回的是數(shù)字。
2> pull可以在程序中控制,想解析到哪里就可以停止到哪里
3> android中推薦使用pull解析
---------------------------------------------SAX解析xml------------------------------------------
1> 解析效率高,占用內(nèi)存少
2> 可以隨時(shí)停止解析
3> 不能載入整個(gè)文檔到內(nèi)存
4> 不能寫入xml
5> SAX解析xml文件采用的是事件驅(qū)動(dòng)
4. Java與C++對(duì)比。
java是[ sun ]公司開發(fā)的。c++是[ 微軟公司 ]開發(fā)的。
用途不同:C++和JAVA 表面上看,JAVA 比較優(yōu)秀的地方就是跨平臺(tái),也就是程序移植!而C++移植方面不入JAVA,而C++的閃光點(diǎn),就是程序性能,運(yùn)行速度,執(zhí)行效率!C++一般用于開發(fā)系統(tǒng)程序,大型程序,驅(qū)動(dòng)等... 對(duì)性能要求比較高的東西,而java的閃光點(diǎn),一般在網(wǎng)頁上,或者小型的軟件上!但java的執(zhí)行效率明顯不如C++ 因?yàn)樗縥ava虛擬機(jī)運(yùn)行java編寫的程序java程序執(zhí)行效率不高,但開發(fā)效率要比C++要高!
5. Java1.7與1.8新特性。
**ps: ** 如想全面了解jdk新特性可以自行進(jìn)入官網(wǎng)深入學(xué)習(xí),這里只做常用api的介紹。
個(gè)人認(rèn)為比較牛逼的兩點(diǎn)Java 1.8新特性如下:
1> 接口中實(shí)現(xiàn)具體方法、靜態(tài)方法。代碼如下:
interface Interface_ {
// 普通方法
void v();
// default修飾的具體方法
default void vv() {System.out.println("default void vv()");}
// 靜態(tài)方法
static void staticMethod(){System.out.println("測(cè)試靜態(tài)方法");}
}
public static void main(String[] args) {
Interface_ i = new Interface_() {
@Override
public void v() {
// TODO Auto-generated method stub
}
@Override
public void vv() {
// TODO Auto-generated method stub
Interface_.super.vv();
System.out.println("Auto-generated method stub");
}
};
i.vv();
Interface_.staticMethod();
}
2> lambda函數(shù)和表達(dá)式效果如下:
ps: 這個(gè)建議直接跑demo看效果,是不是覺得碉堡了呢,如果還不錯(cuò)?還不抓緊關(guān)注帥比楊~!
public static void main(String[] args) {
List<String> languages = Arrays.asList("Java", "Scala", "C++","Haskell", "Lisp", "JavaScript");
System.out.println("Languages which starts with J :");
filter(languages, (str) -> ((String) str).startsWith("J"));
System.out.println("Languages which ends with a ");
filter(languages, (str) -> ((String) str).endsWith("a"));
System.out.println("Print all languages :");
filter(languages, (str) -> true);
System.out.println("Print no language : ");
filter(languages, (str) -> false);
System.out.println("Print language whose length greater than 4:");
filter(languages, (str) -> ((String) str).length() > 4);
}
public static void filter(List<String> names, Predicate<String> condition) {
names.stream().filter((name) -> (condition.test(name)))
.forEach((name) -> {
System.out.println(name + " ");
});
}
個(gè)人認(rèn)為比較牛逼的兩點(diǎn)Java 1.7新特性如下:
**1>switch中可以使用字串 **
public static void main(String[] args) {
String s = "test";
switch (s) {
case "test":
System.out.println("test");
break;
case "test1":
System.out.println("test1");
break;
default:
System.out.println("break");
break;
}
}
2> 在Java 1.7里,一個(gè)catch可以捕獲多個(gè)異常,這樣可以減少重復(fù)代碼。每個(gè)異常之間用 "|" 隔開。
try {
BufferedReader reader = new BufferedReader(new FileReader(""));
Connection con = null;
Statement stmt = con.createStatement();
} catch (IOException | SQLException e) {
e.printStackTrace();
}
6. 設(shè)計(jì)模式:?jiǎn)卫⒐S、適配器、責(zé)任鏈、觀察者等等。
設(shè)計(jì)模式: 設(shè)計(jì)模式(Design pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過分類編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。
單例模式(Singleton Pattern)
單例模式約束了一個(gè)類的實(shí)例化并且確保在JVM中只會(huì)存在一個(gè)類的實(shí)例。這個(gè)看起來非常簡(jiǎn)單的設(shè)計(jì)模式但是在實(shí)現(xiàn)起來的時(shí)候會(huì)帶來很多的實(shí)現(xiàn)問題。單例模式的實(shí)現(xiàn)在開發(fā)中中通常是一個(gè)有爭(zhēng)議性的話題。看下Singleton Design Pattern文章來了解到實(shí)現(xiàn)單例模式的不同方法還有每個(gè)方法的優(yōu)點(diǎn)和缺點(diǎn)。
** 工廠模式(Factory) **
定義:用一個(gè)方法去代替構(gòu)造器或者是new關(guān)鍵字,把創(chuàng)建的對(duì)象隱藏起來。
優(yōu)點(diǎn)如下:
1> 隱蔽了new關(guān)鍵字和構(gòu)造器
2> 降低了這個(gè)對(duì)象與別的類之間的耦合度,提高了程序的可擴(kuò)展性
原因:當(dāng)子類被別的類替換,或者構(gòu)造器的參數(shù)發(fā)生變化的時(shí)候,只需改動(dòng)工廠方 法內(nèi)的new即可,改動(dòng)量降到了最低,而如果不用工廠模式,直接用new關(guān)鍵字的話,需要改動(dòng)的地方就很多了。
3> 把對(duì)象的設(shè)計(jì)和實(shí)現(xiàn)分割開來,從而代碼擴(kuò)展性強(qiáng)、靈活性更高。
解決問題:用來解決一個(gè)一個(gè)類的生成方式過多,容易發(fā)生變動(dòng),或者是父類和子類之間容易替換的地方。
適配器模式(Adapter Pattern)
適配器設(shè)計(jì)模式是一個(gè)結(jié)構(gòu)型的設(shè)計(jì)模式,它用于將兩個(gè)沒有關(guān)系的接口可以在一起起作用。將這些無關(guān)的接口組合在一起的對(duì)象就是一個(gè)適配器。拿生活中一個(gè)實(shí)際的場(chǎng)景,我們可以把手機(jī)充電器當(dāng)成是一個(gè)適配器因?yàn)槭謾C(jī)電池需要使用3V的電,但是一般情況下電插板只是產(chǎn)生120V或者240V的電。所以手機(jī)充電器就是在手機(jī)充電板和正常充電板充當(dāng)一個(gè)適配器的。看下文章Adapter Pattern來看下它是如何在Java中應(yīng)用的。
責(zé)任鏈模式(Chain of Responsibility Pattern)
責(zé)任鏈模式用于在軟件設(shè)計(jì)中有來自客戶端的請(qǐng)求需要傳遞給一串對(duì)象來處理的場(chǎng)景中解耦的。在鏈中的對(duì)象將會(huì)決定誰將處理這個(gè)情況并且這個(gè)請(qǐng)求是否需要傳遞給鏈中的下一個(gè)對(duì)象。我們清楚我們?cè)谝粋€(gè)try-cathc代碼塊中可以有多個(gè)catch塊。這里每一個(gè)catch塊都是一種形式的處理器去處理特殊的異常。所以當(dāng)在try中出現(xiàn)任何異常的時(shí)候,它會(huì)傳遞給第一個(gè)catch塊。如果catch塊沒辦法處理它,它會(huì)將情況傳遞給下個(gè)對(duì)象。即使最后一個(gè)catch塊沒辦法處理它,那么異常將會(huì)拋出到鏈的外面到調(diào)用它的程序。
ATM分發(fā)機(jī)邏輯就是使用了Chain of Responsibility Pattern的實(shí)現(xiàn),看下鏈接。
觀察者模式(Observer Pattern)
觀察者模式在你對(duì)一個(gè)對(duì)象的狀態(tài)感興趣并且希望在任何時(shí)候發(fā)生改變的時(shí)候都能夠得到通知的場(chǎng)景下是很有用的。在觀察者模式中,觀察其他對(duì)象的狀態(tài)的對(duì)象被稱為Observer,而被觀察的對(duì)象被稱為Subject。
Java通過java.util.Observable類和java.util.Observer接口提供了內(nèi)置的觀察者模式的實(shí)現(xiàn)。的但是因?yàn)檫@個(gè)實(shí)現(xiàn)非常的簡(jiǎn)單而且大部分的時(shí)候我們不想通過擴(kuò)展一個(gè)類來實(shí)現(xiàn)觀察者模式因?yàn)閖ava不提供類的多繼承,所以它被使用的不廣泛。
Java消息服務(wù)(JMS)使用中介者模式中在介者模式中一塊來允許應(yīng)用來訂閱和發(fā)布數(shù)據(jù)到其他的應(yīng)用中。看文章Observer Pattern來具體的實(shí)現(xiàn)和示例程序。
7. JNI的使用。
**概述: **
JNI,是Java Native Interface的縮寫,中文為Java本地調(diào)用。通俗地說,JNI是一種技術(shù),通過這種技術(shù)可以做到以下兩點(diǎn):
1> Java程序中的函數(shù)可以調(diào)用Native語言寫的函數(shù),Native一般指的是C/C++編寫的函數(shù)。
2> Native程序中的函數(shù)可以調(diào)用Java層的函數(shù),也就是在C/C++程序中可以調(diào)用Java的函數(shù)。
JNI 開發(fā)流程主要分為以下 6 步:
1> 編寫聲明了 native 方法的 Java 類
2> 將 Java 源代碼編譯成 class 字節(jié)碼文件
3> 用 javah -jni 命令生成.h頭文件(javah 是 jdk 自帶的一個(gè)命令,-jni 參數(shù)表示將 class 中用native 聲明的函數(shù)生成 JNI 規(guī)則的函數(shù))
4> 用本地代碼實(shí)現(xiàn).h頭文件中的函數(shù)
5> 將本地代碼編譯成動(dòng)態(tài)庫(Windows:*.dll,linux/unix:*.so,mac os x:*.jnilib)
6> 拷貝動(dòng)態(tài)庫至 java.library.path 本地庫搜索目錄下,并運(yùn)行 Java 程序
具體流程可以參考這篇文章http://wiki.jikexueyuan.com/project/jni-ndk-developer-guide/workflow.html
ps: 喜歡有幫助的話: 雙擊、評(píng)論、轉(zhuǎn)發(fā),動(dòng)一動(dòng)你的小手讓更多的人知道!關(guān)注 帥比-楊