一篇文章讓你真正瞭解Java

「你學習一門技術的最佳時機是三年前,其次是如今。」這句話對於哪種行業都很適用,若是你已經學習過Java,那麼恭喜你你頗有先見之明,若是你並不瞭解Java,這篇文章帶你快速掌握Java的幾個核心知識點。java

1、Java特色程序員

一、 面向對象算法

儘管受到其前輩的影響,但Java沒被設計成兼容其餘語言源代碼的程序。這容許Java開發組自由地從零開始。這樣作的一個結果是,Java語言能夠更直接、更易用、更實際的接近對象。Java的對象模型既簡單又容易擴展,對於簡單數據類型,例如整數,它保持了高性能,但不是對象。編程

二、 解釋性和高性能數組

字節碼能夠在提供Java虛擬機(JVM)的任何一種系統上被解釋執行。早先的許多嘗試解決跨平臺的方案對性能要求都很高。其餘解釋執行的語言系統,如BASIC,Tcl,PERL都有沒法克服的性能缺陷。然而,Java卻能夠在很是低檔的CPU上順利運行。前面已解釋過,Java確實是一種解釋性語言,Java的字節碼通過仔細設計,於是很容易便能使用JIT編譯技術將字節碼直接轉換成高性能的本機代碼。Java運行時系統在提供這個特性的同時仍具備平臺獨立性,於是「高效且跨平臺」對Java來講再也不矛盾。安全

三、 動態數據結構

Java程序帶有多種的運行時類型信息,用於在運行時校驗和解決對象訪問問題。這使得在一種安全、有效的方式下動態地鏈接代碼成爲可能,對小應用程序環境的健壯性也十分重要,由於在運行時系統中,字節碼內的小段程序能夠動態地被更新。jvm

2、面向對象的編程編程語言

2.1 抽象函數

面向對象編程的一個實質性的要素是抽象。人們經過抽象(abstraction)處理複雜性。

例如,人們不會把一輛汽車想象成由幾萬個互相獨立的部分所組成的一套裝置,而是把汽車想成一個具備本身獨特行爲的對象。這種抽象令人們能夠很容易地將一輛汽車開到雜貨店,而不會因組成汽車各部分零件過於複雜而不知所措。傳統的面向過程程序的數據通過抽象可用若干個組成對象表示,程序中的過程步驟可當作是在這些對象之間進行消息收集。這樣,每個對象都有它本身的獨特行爲特徵。你能夠把這些對象看成具體的實體,讓它們對告訴它們作什麼事的消息做出反應。這是面向對象編程的本質。面向對象的概念是Java 的核心。

2.2面向對象編程的3個原則

全部面向對象的編程語言都提供幫助你實現面向對象模型的機制,這些機制是封裝,繼承及多態性。如今讓咱們來看一下它們的概念。

封裝

封裝(Encapsulation)是將代碼及其處理的數據綁定在一塊兒的一種編程機制,該機制保證了程序和數據都不受外部干擾且不被誤用。理解封裝性的一個方法就是把它想成一個黑匣子,它能夠阻止在外部定義的代碼隨意訪問內部代碼和數據。對黑匣子內代碼和數據的訪問經過一個適當定義的接口嚴格控制。

Java封裝的基本單元是類。儘管類將在之後章節詳細介紹。如今仍有必要對它做一下簡單的討論。類是一種邏輯結構,而對象是真正存在的物理實體。若是你對C/C++熟悉,能夠這樣理解:Java程序員所稱的方法,就是C/C++程序員所稱的函數(function)。在徹底用Java編寫的程序中,方法定義如何使用成員變量。這意味着一個類的行爲和接口是經過方法來定義的,類這些方法對它的實例數據進行操做。

繼承

繼承(Inheritance)是一個對象得到另外一個對象的屬性的過程。繼承很重要,由於它支持了按層分類的概念。使用了繼承,一個對象就只需定義使它在所屬類中獨一無二的屬性便可,由於它能夠從它的父類那兒繼承全部的通用屬性。

繼承性與封裝性相互做用。若是一個給定的類封裝了一些屬性,那麼它的任何子類將具備一樣的屬性,並且還添加了子類本身特有的屬性。這是面向對象的程序在複雜性上呈線性而非幾何性增加的一個關鍵概念。新的子類繼承它的全部祖先的全部屬性。它不與系統中其他的多數代碼產生沒法預料的相互做用。

多態性

多態性是容許一個接口被多個同類動做使用的特性,具體使用哪一個動做與應用場合有關,下面咱們以一個後進先出型堆棧爲例進行說明。假設你有一個程序,須要3種不一樣類型的堆棧。一個堆棧用於整數值,一個用於浮點數值,一個用於字符。儘管堆棧中存儲的數據類型不一樣,但實現每一個棧的算法是同樣的。若是用一種非面向對象的語言,你就要建立3個不一樣的堆棧程序,每一個程序一個名字。可是,若是使用Java,因爲它具備多態性,你就能夠建立一個通用的堆棧程序集,它們共享相同的名稱。多態性的概念常常被說成是「一個接口,多種方法」。這意味着能夠爲一組相關的動做設計一個通用的接口。多態性容許同一個接口被必於同一類的多個動做使用,這樣就下降了程序的複雜性。選擇應用於每一種情形的特定的動做(specific action)(即方法)是編譯器的任務,程序員無需手工進行選擇。你只需記住而且使用通用接口便可。

3、 hashmap hashtable

HashMap 是一個散列表,它存儲的內容是鍵值對(key-value)映射。HashMap 繼承於AbstractMap,實現了Map、Cloneable、java.io.Serializable接口。

HashMap 的實現不是同步的,這意味着它不是線程安全的。它的key、value均可覺得null。此外,HashMap中的映射不是有序的。HashMap的實例有兩個參數影響其性能:「初始容量」 和 「加載因子」。容量是哈希表中桶的數量,初始容量 只是哈希表在建立時的容量。加載因子 是哈希表在其容量自動增長以前能夠達到多滿的一種尺度。當哈希表中的條目數超出了加載因子與當前容量的乘積時,則要對該哈希表進行 rehash 操做(即重建內部數據結構),從而哈希表將具備大約兩倍的桶數。

四. jvm 內存模型

程序計數器

每一個線程有要有一個獨立的程序計數器,記錄下一條要運行的指令。線程私有的內存區域。若是執行的是JAVA方法,計數器記錄正在執行的java字節碼地址,若是執行的是native方法,則計數器爲空。

虛擬機棧

線程私有的,與線程在同一時間建立。管理JAVA方法執行的內存模型。

本地方法區

和虛擬機棧功能類似,但管理的不是JAVA方法,是本地方法

方法區

線程共享的,用於存放被虛擬機加載的類的元數據信息:如常量、靜態變量、即時編譯器編譯後的代碼。也稱爲永久代。

JAVA 堆

線程共享的,存放全部對象實例和數組。垃圾回收的主要區域。能夠分爲新生代和老年代(tenured)。

5、 運行時類型信息(RTTI + 反射)

概念—RTTI:運行時類型信息使得你能夠在程序運行時發現和使用類型信息。

使用方式:Java是如何讓咱們在運行時識別對象和類的信息的,主要有兩種方式(還有輔助的第三種方式,見下描述):

一種是「傳統的」RTTI,它假定咱們在編譯時已經知道了全部的類型,好比Shape s = (Shape)s1;另外一種是「反射」機制,它運行咱們在運行時發現和使用類的信息,即便用Class.forName()。其實還有第三種形式,就是關鍵字instanceof,它返回一個bool值,它保持了類型的概念,它指的是「你是這個類嗎?或者你是這個類的派生類嗎?」。而若是用==或equals比較實際的Class對象,就沒有考慮繼承—它或者是這個確切的類型,或者不是。

工做原理

要理解RTTI在Java中的工做原理,首先必須知道類型信息在運行時是如何表示的,這項工做是由稱爲Class對象的特殊對象完成的,它包含了與類有關的信息。Java送Class對象來執行其RTTI,使用類加載器的子系統實現。

不管什麼時候,只要你想在運行時使用類型信息,就必須首先得到對恰當的Class對象的引用

反射與RTTI的區別

RTTI與反射之間真正的區別只在於:對RTTI來講,編譯器在編譯時打開和檢查.class文件(也就是能夠用普通方法調用對象的全部方法);而對於反射機制來講,.class文件在編譯時是不可獲取的,因此是在運行時打開和檢查.class文件。

六. 即時編譯器技術 — JIT

Java虛擬機中有許多附加技術用以提高速度,尤爲是與加載器操做相關的,被稱爲「即時」(Just-In-Time,JIT)編譯器的技術。這種技術能夠把程序所有或部分翻譯成本地機器碼(這原本是JVM的工做),程序運行速度所以得以提高。當須要裝載某個類時,編譯器會先找到其.class文件,而後將該類的字節碼裝入內存。此時,有兩種方案可供選擇:

(1)一種就是讓即時編譯器編譯全部代碼。

(2)另外一種作法稱爲惰性評估(lazy evaluation),意思是即時編譯器只在必要的時候才編譯代碼,這樣,從不會被執行的代碼也許就壓根不會被JIT所編譯。

7、 final關鍵字

對final關鍵字的誤解

當final修飾的是基本數據類型時,它指的是數值恆定不變(就是編譯期常量,若是是static final修飾,則強調只有一份),而對對象引用而不是基本類型運用final時,其含義會有一點使人迷惑,由於用於對象引用時,final使引用恆定不變,一旦引用被初始化指向一個對象,就沒法再把它指向另外一個對象。然而,對象其自身倒是能夠被修改的,Java並未提供使任何對象恆定不變的途徑(但能夠本身編寫類以取得使對象恆定不變的效果),這一限制一樣適用數組,它也是對象。

相關文章
相關標籤/搜索