Java學(xué)習(xí)筆記 - 第001天

概述

在過去的20年里,如果要選一個(gè)最成功的編程語言那一定非Java莫屬。根據(jù)TIOBE Index發(fā)布的編程語言排行榜,自2001年以來Java語言在這個(gè)排行榜上最差的名次是第二名。在20年的發(fā)展歷程中,Java已經(jīng)不僅僅是一門編程語言,它更是一個(gè)平臺(tái),是一系列的計(jì)算機(jī)軟件和規(guī)范形成的技術(shù)體系,從嵌入式系統(tǒng)、移動(dòng)終端到個(gè)人計(jì)算機(jī)、服務(wù)器等領(lǐng)域,Java都占據(jù)著舉足輕重的位置。按照官方網(wǎng)站在2016年提供的數(shù)據(jù),全球有900萬Java開發(fā)人員并有約60億臺(tái)設(shè)備都在運(yùn)行Java程序,這些數(shù)字都是非常震撼的。

術(shù)語

想了解Java,有三個(gè)術(shù)語必須要知道:

JDK:Java開發(fā)者工具 - Java Developer's Kit
JRE:Java運(yùn)行時(shí)環(huán)境 - Java Runtime Environment
JVM:Java虛擬機(jī) - Java Virtual Machine

歷史

關(guān)于Java這20年的故事,不是一兩句話能說清楚的,下面用編年史的方式做一個(gè)簡(jiǎn)要的介紹。

  • 1991年4月,James Gosling(計(jì)算機(jī)界的全能奇才,被稱為“Java之父”)領(lǐng)導(dǎo)的Green Project啟動(dòng),雖然項(xiàng)目項(xiàng)目并不成功,但是在項(xiàng)目中誕生的Oak語言伴隨著互聯(lián)網(wǎng)潮流的興起,迅速找到了適合自己發(fā)展的市場(chǎng)定位并最終蛻變?yōu)镴ava語言。
  • 1995年5月23日,Java誕生。
  • 1996年1月23日,JDK 1.0正式發(fā)布。
  • 1996年5月,第一屆JavaOne大會(huì)在舊金山舉行。
  • 1997年2月19日, SUN公司發(fā)布JDK 1.1,代表性的技術(shù)包括:JAR文件格式、JDBC、JavaBeans、RMI、內(nèi)部類和反射等。
  • 1998年12月4日,JDK迎來了里程碑式的版本JDK 1.2,SUN公司將Java技術(shù)拆分為3個(gè)方向,分別是面向桌面應(yīng)用開發(fā)的J2SE、面向企業(yè)級(jí)開發(fā)的J2EE和面向移動(dòng)終端開發(fā)的J2ME。該版本首次在Java虛擬機(jī)中內(nèi)置了JIT編譯器。
  • 2000年5月8日,JDK 1.3發(fā)布,代號(hào)Kestrel,改進(jìn)了數(shù)學(xué)運(yùn)算、時(shí)間以及Java 2D等API,新增了和聲音處理相關(guān)的類庫(kù)。此后,SUN公司基本每個(gè)兩年發(fā)布一個(gè)JDK的主版本,產(chǎn)品代號(hào)都以動(dòng)物命名。
  • 2002年2月13日,JDK 1.4發(fā)布,代號(hào)Merlin,Java開始走向成熟并逐漸達(dá)到巔峰,今天很多主流框架仍然可以在JDK 1.4上直接運(yùn)行。該版本中引入了正則表達(dá)式、異常鏈、NIO、日志類、XML解析器等。
  • 2004年9月30日,JDK 1.5發(fā)布,代號(hào)Tiger,該版本在Java語法的易用性上做出了很大的改進(jìn),引入了自動(dòng)裝箱、泛型、注解、枚舉、可變參數(shù)列表、for-each循環(huán)等特性,同時(shí)在這個(gè)版本中還對(duì)Java內(nèi)存模型進(jìn)行了改進(jìn),同時(shí)引入了更優(yōu)質(zhì)的用于多線程編程的java.util.concurrent包。
  • 2006年12月11日,JDK 1.6發(fā)布,代號(hào)Mustang,在這個(gè)版本中,J2SE、J2EE和J2ME被更名為Java SE、Java EE和Java ME,提供了對(duì)腳本語言的支持以及編譯器API和微型HTTP服務(wù)器API等內(nèi)容。此外,該版本還對(duì)Java虛擬機(jī)內(nèi)部進(jìn)行了大量的優(yōu)化,包括垃圾回收、類加載、鎖機(jī)制等。同年,SUN公司開始逐漸陷入困境。
  • 2009年2月19日,JDK 1.7發(fā)布,代號(hào)Dolphin,JDK 1.7最初計(jì)劃引入很多開發(fā)者翹首以盼的功能,包括Lambda表達(dá)式,Jigsaw項(xiàng)目、動(dòng)態(tài)語言支持、G1收集器和Coin項(xiàng)目,但是如前所述,由于SUN公司已經(jīng)陷入困境,無力推動(dòng)研發(fā)工作按正常計(jì)劃進(jìn)行,在4月20日Oracle公司宣布以74億美元收購(gòu)SUN公司,Java商標(biāo)從此歸Oracle所有,此后Oracle公司執(zhí)行了所謂的“B計(jì)劃”,大幅裁剪了JDK 1.7的預(yù)定目標(biāo),把諸多內(nèi)容推遲到了JDK 1.8中,隨后又宣布Jigsaw在JDK 1.8中依然無法完成。
  • 2014年3月18日,在漫長(zhǎng)的等待后,“跳票王”O(jiān)racle公司終于推出了JDK 1.8,沒有產(chǎn)品代號(hào),這一次真可以說得上是“千呼萬喚始出來”。

特點(diǎn)

自Java誕生以來,你可能聽過很多關(guān)于Java有多么牛逼的描述,但是其中很多內(nèi)容都是過去時(shí),當(dāng)下的Java最吸引人的地方應(yīng)該在于以下幾個(gè)方面。

  • 對(duì)函數(shù)式編程的支持:面向?qū)ο蟮木幊趟枷胱寫?yīng)用程序的開發(fā)變得簡(jiǎn)單輕松,通過給對(duì)象發(fā)送消息很多問題就可以得到解決;而函數(shù)式編程的思想則源于λ 演算,強(qiáng)調(diào)使用表達(dá)式而不是語句,通過不改變狀態(tài)的操作讓代碼沒有副作用,這些都迎合了很多領(lǐng)域的開發(fā)者的需求,當(dāng)下很多高級(jí)編程語言都提供了對(duì)函數(shù)式編程的支持,Java終于在JDK 1.8中引入了Lambda表達(dá)式、函數(shù)式接口、方法引用等高級(jí)語法來支持函數(shù)式編程,且看一小段代碼。
import java.util.List;
import java.util.Arrays;
class Hello {
  public static void main(String[] args) {
      List<String> list = Arrays.asList("apple", "grape", "pitaya");
      list.forEach(System.out::println);
  }
}
  • 始終如一的平臺(tái)可移植性:平臺(tái)可移植性從來都是Java最大的賣點(diǎn),通過在不同的平臺(tái)下安裝對(duì)應(yīng)的JVM來加載類文件執(zhí)行,雖然在犧牲了執(zhí)行效率,但獲得的是完美的平臺(tái)可移植性。
  • 支持多種編程語言混編:目前的JVM已經(jīng)能夠支持諸如Groovy、Scala、Clojure這樣的語言進(jìn)行開發(fā)。使用非Java語言主要是出于這些考慮:首先使用領(lǐng)域特定語言可以方便構(gòu)建、持續(xù)集成、業(yè)務(wù)規(guī)則建模等操作;其次也可以利用一些動(dòng)態(tài)語言的特性來彌補(bǔ)Java本身的不足,滿足快速Web開發(fā)、腳本編程和測(cè)試等方面的需求。今天有很多軟件和系統(tǒng)的開發(fā)都是通過多語言混編實(shí)現(xiàn)的。
  • 對(duì)多核并發(fā)編程的支持:Java語言內(nèi)置的對(duì)多線程編程的支持是Java早期的一大賣點(diǎn),但在今天看來已經(jīng)不是什么了不起的事情。隨著CPU進(jìn)入多核時(shí)代,Java在并發(fā)編程上也做出了與時(shí)俱進(jìn)的升級(jí),從JDK 1.5的java.util.concurrent包,到JDK 1.7引入Fork/Join模式,Java程序已經(jīng)能夠輕松的利用多個(gè)CPU核心提供的計(jì)算能力來協(xié)作完成更復(fù)雜的任務(wù)。

探秘

想要深入學(xué)習(xí)和了解Java,可以對(duì)JVM進(jìn)行一次探秘。

JVM中的內(nèi)存

  • 程序計(jì)數(shù)器(Program Counter Register)程序計(jì)數(shù)器可以視為當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器,字節(jié)碼解釋器工作時(shí)就是通過改變程序計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令。對(duì)于多線程的應(yīng)用程序,每個(gè)線程都需要有一個(gè)獨(dú)立的程序計(jì)數(shù)器,線程之間互不影響,因此程序計(jì)數(shù)器是線程私有的內(nèi)存。
  • 虛擬機(jī)棧(VM Stack)
    Java虛擬機(jī)棧也是線程私有的,它描述了Java方法執(zhí)行的內(nèi)存模型,即每個(gè)方法在執(zhí)行時(shí)都會(huì)創(chuàng)建一個(gè)棧幀用于存儲(chǔ)局部變量表(存放了編譯期可知的基本數(shù)據(jù)類型,包括:byte、short、int、long、float、double、char、boolean,對(duì)象的引用以及返回地址)、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息。在JVM規(guī)范中,對(duì)這個(gè)區(qū)域規(guī)定了兩種異常狀況:如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度,將引發(fā)StackOverflowError;如果虛擬機(jī)棧需要擴(kuò)展空間但無法申請(qǐng)到足夠的內(nèi)存,將引發(fā)OutOfMemoryError。
  • 本地方法棧(Native Method Stack)
    本地方法棧顧名思義是調(diào)用本地方法(用C/C++編寫的方法)時(shí)使用的棧。
  • 堆(Heap)
    堆是JVM所管理的內(nèi)存中最大的一塊,它是被所有線程共享的內(nèi)存區(qū)域,在JVM啟動(dòng)時(shí)創(chuàng)建,用于存放對(duì)象實(shí)例。在JVM規(guī)范中明確指出:The heap is the runtime data area from which memory for all class instances and arrays is allocated. 但是隨著JIT編譯器的發(fā)展與逃逸分析技術(shù)的逐漸成熟,對(duì)象實(shí)例的棧上分配、標(biāo)量替換優(yōu)化將使得“對(duì)象一定在堆上”這個(gè)說法變得不那么絕對(duì)了。堆是Java垃圾收集器管理的主要區(qū)域,現(xiàn)在的垃圾收集器都基于分代收集算法,堆通常分為新生代和老生代,新生代具體又可細(xì)分為Eden、From Survivor和To Survivor。在啟動(dòng)JVM時(shí)可以通過-Xmx和-Xms來控制堆的大小,還可以通過-Xmn和-XX:NewRatio來控制新生代的大小以及新生代和老生代的比例,如果想了解垃圾收集器的工作細(xì)節(jié),可以使用-XX:+PrintGCDetails來做到。
Paste_Image.png
  • 方法區(qū)(Method Area)
    方法區(qū)也是線程共享的內(nèi)存區(qū)域,用于存儲(chǔ)已被JVM加載的類的信息、常量、靜態(tài)變量、JIT編譯后的代碼等數(shù)據(jù)。方法區(qū)中比較重要的一塊是運(yùn)行時(shí)常量池(Constant Pool),它允許運(yùn)行期間將新的常量放入池中,String類的intern()方法就是一個(gè)例子。當(dāng)常量池?zé)o法再申請(qǐng)到內(nèi)存時(shí)也會(huì)引發(fā)OutOfMemoryError。
  • 直接內(nèi)存
    JDK1.4中引入了NIO(非阻塞式I/O),它可以使用本地方法分配堆以外的內(nèi)存,然后通過ByteBuffer/CharBuffer對(duì)象來操作這些內(nèi)存,從而實(shí)現(xiàn)提升性能的目標(biāo)。

說明:Java虛擬機(jī)是非常復(fù)雜的,如果想要真正理解它的工作原理,可以嘗試自己寫一個(gè)Java虛擬機(jī)。不要覺得這件事情遙不可及,有一本名為《自己動(dòng)手寫Java虛擬機(jī)》的書就用Go語言實(shí)現(xiàn)了一個(gè)自己的JVM。

JVM中的對(duì)象

  • 對(duì)象的創(chuàng)建
    虛擬機(jī)遇到一條new指令時(shí),首先將檢查這個(gè)指令對(duì)應(yīng)的參數(shù)是不是能在常量池中定位到的一個(gè)類的符號(hào)引用,然后還要檢查這個(gè)對(duì)應(yīng)的類是否已經(jīng)被加載、解析和初始化過,如果沒有就要執(zhí)行類加載(具體的細(xì)節(jié)將在后續(xù)的文章中探討)。接下來需要為對(duì)象分配內(nèi)存空間,而且內(nèi)存空間除對(duì)象頭外都要被初始化為0值,這就保證了對(duì)象的屬性在不賦初始值的情況下就能直接使用。再下來,JVM要對(duì)對(duì)象進(jìn)行必要的設(shè)置,主要是對(duì)象頭的設(shè)置以及對(duì)象的初始化工作(按照程序員的意愿為屬性設(shè)定對(duì)應(yīng)的值),到此一個(gè)對(duì)象就真正的完成了創(chuàng)建過程。
  • 對(duì)象的內(nèi)存布局
    對(duì)于HotSpot虛擬機(jī)而言,對(duì)象在內(nèi)存中的布局可以為分3塊區(qū)域:對(duì)象頭、實(shí)力數(shù)據(jù)和對(duì)齊填充。對(duì)象頭包含兩部分信息,第一部分用于存儲(chǔ)對(duì)象自身的運(yùn)行時(shí)數(shù)據(jù),如哈希碼、GC分代年齡、鎖狀態(tài)標(biāo)識(shí)等;另一部分是類型指針,也就是對(duì)象指向它的類元數(shù)據(jù)的指針,虛擬機(jī)通過這個(gè)指針來確定這個(gè)對(duì)象是哪個(gè)類的實(shí)例。
  • 對(duì)象的訪問定位

開發(fā)

如果只想運(yùn)行Java程序,那么有JRE就足夠了,因?yàn)樗诉\(yùn)行Java程序所需的虛擬機(jī)還有就是支撐程序運(yùn)行的上下文環(huán)境;如果想要用Java開發(fā)應(yīng)用程序那么就得有JDK,因?yàn)镴DK中包含了Java開發(fā)的必要工具。當(dāng)然,在開發(fā)過程中使用IDE(集成開發(fā)環(huán)境)可以大大提升開發(fā)效率。對(duì)于Java開發(fā)而言,可以選擇的IDE主要有三個(gè):

  • Eclipse:國(guó)內(nèi)有很多程序員都在使用Eclipse,因?yàn)樗?jiǎn)單、免費(fèi)、還有很多提升開發(fā)效率的特性。

  • IntelliJ:集成的插件和功能較多,代碼提示和修復(fù)能力強(qiáng)大,可以根據(jù)需求對(duì)IDE進(jìn)行定制,有免費(fèi)和付費(fèi)兩種版本,后者支持的功能更多更強(qiáng)大。

Paste_Image.png
  • NetBeans:我自己使用這個(gè)IDE的次數(shù)非常少,因此也只能說這是官方提供的開發(fā)工具。

書籍

  • 入門讀物:Core Java(中文名:《Java核心技術(shù)》,目前最新的版本是第10版,非常棒的入門書?。?/li>
  • 進(jìn)階讀物:Thinking in Java(中文名:《Java編程思想》)、Effective Java(提升Java水平必讀書籍)、Refactor(中文名《重構(gòu):改善既有代碼設(shè)計(jì)》,編程大師Martin Fowler神作)、《Java與模式》(美籍華人閻宏博士力作)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,757評(píng)論 11 349
  • 從今天開始讀《深入理解 Java 虛擬機(jī)》一書,并開設(shè)了同名專題 深入理解 Java 虛擬機(jī)。計(jì)劃在 2 周內(nèi)將全...
    SawyerZh閱讀 10,441評(píng)論 17 215
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,626評(píng)論 18 399
  • 一直聽大家說奇葩說,也在推薦看奇葩說,今天終于行動(dòng)了從第一季開始看, 因?yàn)橛杏嗛喠撕煤谜f話,對(duì)一些人名有一些熟悉,...
    我是王同學(xué)閱讀 307評(píng)論 0 0
  • 希望,奢望。眼前,遙遠(yuǎn)。分過,合過。 失望,絕望。夢(mèng)醒,結(jié)束。恨過,痛過。 祈求,奢求。承諾,謊言。哭過,傷過。 ...
    一朵愁云閱讀 183評(píng)論 0 0

友情鏈接更多精彩內(nèi)容