Java『基礎(chǔ)知識』

JVM

JVM是運行Java字節(jié)碼的虛擬機(jī)搀继。JVM有針對不同系統(tǒng)的特定實現(xiàn)叽躯,目的在不同的系統(tǒng)平臺上運行相同的字節(jié)碼啡专。.java文件經(jīng)過JDK的javac編譯為.class文件们童,.class文件又被JVM編譯成機(jī)器可執(zhí)行的二進(jìn)制機(jī)器碼慧库。

我們需要格外注意的是 .class->機(jī)器碼 這一步齐板。在這一步 jvm 類加載器首先加載字節(jié)碼文件甘磨,然后通過解釋器逐行解釋執(zhí)行,這種方式的執(zhí)行速度會相對比較慢卿泽。而且签夭,有些方法和代碼塊是經(jīng)常需要被調(diào)用的椎侠,也就是所謂的熱點代碼我纪,所以后面引進(jìn)了 JIT 編譯器璧诵,JIT 屬于運行時編譯仇冯。當(dāng) JIT 編譯器完成第一次編譯后比被,其會將字節(jié)碼對應(yīng)的機(jī)器碼保存下來等缀,下次可以直接使用尺迂。而我們知道噪裕,機(jī)器碼的運行效率肯定是高于 Java 解釋器的膳音。這也解釋了我們 為什么經(jīng)常會說 Java 是編譯與解釋共存的語言祭陷。

HotSpot采用了惰性評估(Lazy Evaluation)的做法兵志,根據(jù)二八定律,消耗大部分系統(tǒng)資源的只有那一小部分的代碼(熱點代碼)哑蔫,而這也就是JIT所需要編譯的部分闸迷。JVM會根據(jù)代碼每次被執(zhí)行的情況收集信息并相應(yīng)地做出一些優(yōu)化俘枫,因此執(zhí)行的次數(shù)越多,它的速度就越快今阳。JDK 9引入了一種新的編譯模式AOT(Ahead of Time Compilation)盾舌,它是直接將字節(jié)碼編譯成機(jī)器碼,這樣就避免了JIT預(yù)熱等各方面的開銷蘸鲸。JDK支持分層編譯和AOT協(xié)作使用妖谴。但是 ,AOT 編譯器的編譯質(zhì)量是肯定比不上 JIT 編譯器的酌摇。

重載與重寫

重載:發(fā)生在同一類中膝舅,方法名相同,方法簽名(參數(shù)類型窑多、個數(shù)仍稀、順序不同)可能不同;注意埂息,返回類型和訪問修飾符不算在方法簽名中技潘,不能作為重載的判斷依據(jù)。

重寫:發(fā)生在繼承類中千康,方法簽名需要相同琉闪,方訪問權(quán)限子類中實現(xiàn)需要大于等于父類中實現(xiàn)砂碉。

構(gòu)造器Constructor是否可以被override滴某?

父類的構(gòu)造方法和私有屬性不能被繼承幕侠,所以Constructor也不能被重寫(override)庇忌,但是可以被重載(overload)。

Java面向?qū)ο缶幊倘筇匦?/h4>

封裝、繼承立砸、多態(tài)螺戳,其中多態(tài)指定是程序的引用變量可以在運行時的向上轉(zhuǎn)型動態(tài)確定损同。Java中可以通過繼承接口實現(xiàn)多態(tài)。

String、StringBuilder蛛砰、StringBuffer

可變性:首先String是用final修飾的保存字符的數(shù)組们豌,因為字符串是不可變的,所以當(dāng)直接定義字符串(如:"abc")時,會去常量池中尋找該變量值,存在直接返回使用迟隅,不存在再行創(chuàng)建;StringBuilder和StringBuffer都是繼承自AbstractStringBuilder類瞳步,該類也是使用數(shù)組保存字符串馏臭,和String不同的是沒有使用final修飾,所以是可變的。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
    ...
}

線程安全性:String是不可變的,所以線程安全盗誊;StringBuffer是線程安全的开镣;StringBuilder是非線程安全的卧蜓,所以性能比StringBuffer高一點盛霎。

==和equals()

默認(rèn)情況下==用來比較兩個對象的引用地址是否相同规个,或者比較兩個常量(基礎(chǔ)類型分布在常量池中)是否相等墅拭;equals用來比較對象的具體屬性的值是否相等谍婉;有時我們只需要比較兩個對象包含的屬性值是否相等镀迂,這時可以重寫equals方法來實現(xiàn)招拙。

Object的hashCode()和HashMap中的hashCode()

在使用==判斷兩個變量是否相等规哪,比較的是兩個變量的內(nèi)存地址杯巨,和Object的hashCode()并沒有直接的關(guān)系逗爹;先看Object中的hashCode()

/**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by
     * {@link java.util.HashMap}.
     * <p>
     * The general contract of {@code hashCode} is:
     * <ul>
     * <li>Whenever it is invoked on the same object more than once during
     *     an execution of a Java application, the {@code hashCode} method
     *     must consistently return the same integer, provided no information
     *     used in {@code equals} comparisons on the object is modified.
     *     This integer need not remain consistent from one execution of an
     *     application to another execution of the same application.
     * <li>If two objects are equal according to the {@code equals(Object)}
     *     method, then calling the {@code hashCode} method on each of
     *     the two objects must produce the same integer result.
     * <li>It is <em>not</em> required that if two objects are unequal
     *     according to the {@link java.lang.Object#equals(java.lang.Object)}
     *     method, then calling the {@code hashCode} method on each of the
     *     two objects must produce distinct integer results.  However, the
     *     programmer should be aware that producing distinct integer results
     *     for unequal objects may improve the performance of hash tables.
     * </ul>
     * <p>
     * As much as is reasonably practical, the hashCode method defined by
     * class {@code Object} does return distinct integers for distinct
     * objects. (This is typically implemented by converting the internal
     * address of the object into an integer, but this implementation
     * technique is not required by the
     * Java&trade; programming language.)
     *
     * @return  a hash code value for this object.
     * @see     java.lang.Object#equals(java.lang.Object)
     * @see     java.lang.System#identityHashCode
     */
    public native int hashCode();

首先看到這是一個native方法持舆,方法注釋

  • This method is supported for the benefit of hash tables such as those provided by {@link java.util.HashMap}色瘩,所以這是為什么比較兩個對象是否相等(值相等使用equals,內(nèi)存地址相等使用==)沒有用到hashCode方法逸寓,卻非要在Object類中添加對hashCode的支持的原因居兆;
  • 在同一對象上調(diào)用多次hashCode()應(yīng)該始終返回相同的int值;
  • 如果ObjA.equals(ObjB)竹伸,那么ObjA的hashCode一定等于ObjB泥栖;
  • 兩個對象相互equals,不代表他們的hashCode一定不相等(即所謂的哈希碰撞)勋篓。

其次HashMap只是一種數(shù)據(jù)結(jié)構(gòu)吧享,其存在的理由是為了集成類似數(shù)組的快速查找,又想避免為了存儲少數(shù)大范圍值的數(shù)據(jù)而創(chuàng)建一個大數(shù)組的問題譬嚣。通過hash函數(shù)可以把這些大范圍值的數(shù)據(jù)映射到HashMap的數(shù)組中去钢颂,如果發(fā)生哈希碰撞,則會是使用鏈表拜银,而在Java 8.0以后殊鞭,使用紅黑樹替代了鏈表;

具體HashMap可參考:HashMap實現(xiàn)原理及源碼分析

equals()和hashCode()

? 以HashSet為例尼桶,當(dāng)需要插入操灿、查詢一個對象時,先計算該對象的hashCode,看是否存在相同的hashCode泵督,如果存在趾盐,再對比他們的equals方法是否相等,如果equals方法也相等,則表明是同一個對象谤碳,拒絕插入溃卡;如果equals方法不相等,則對對象的重新進(jìn)行hash蜒简,插入到其他位置瘸羡。

Java中的序列化和反序列化(Serializable)

? Java序列化就是將一個對象轉(zhuǎn)化為一個****二進(jìn)制表示的字節(jié)數(shù)組,如果不想對某些字段進(jìn)行序列化搓茬,可以使用transient關(guān)鍵字修飾犹赖;在反序列化時如果serialVersionUID被修改的話,反序列化會失斁砺亍峻村;當(dāng)父類實現(xiàn)了Serializable接口的時候,所有的子類都能被序列化锡凝,當(dāng)子類實現(xiàn)Serializable接口時粘昨,父類沒有,則父類中的屬性不能被序列化窜锯。

Collections類和Arrays工具類的常用方法

Collections類
  • 排序:sort(List)张肾、sort(List, Comparator)、swap(list, i , j)
  • 查找:binarySearch(list , key)锚扎、max(Collection)吞瞪、indexOfSubList(List list, List target)
  • 替換:replaceAll(List list, Object oldVal, Object newVal)
Arrays類
  • 排序:sort(List)
    val iArray = intArrayOf(1, 3, 4, 5, 6, 7, 8, 8, 6, 5, 4)
        Arrays.sort(iArray)
        for (v in iArray) {
            print("$v ")
        }
    >>>輸出:1 3 4 4 5 5 6 6 7 8 8
  • 比較:equals()
    val arrayA = intArrayOf(1,3,5)
    val arrayB = intArrayOf(1,3,5)
    println(Arrays.equals(arrayA,arrayB))
    >>>輸出:true
  • 轉(zhuǎn)列表:asList()
    val names = Arrays.asList("Larry", "Moe", "Curly")
    println(names)
    >>>輸出:[Larry, Moe, Curly]

Java基礎(chǔ)關(guān)鍵字

final
  • 當(dāng)final用來修飾變量時,如果變量是基本數(shù)據(jù)類型驾孔,則其數(shù)值不能改變芍秆;如果變量時引用類型,則改變量不能在再指向另一個對象翠勉。
  • 當(dāng)一個方法被final修飾時妖啥,表示該方法不能被繼承類重寫。
  • 當(dāng)一個類使用final修飾時眉菱,該類不能被繼承迹栓,該類中所有方法都會隱式的被定義為final方法
static
  • 被static修飾的成員屬于類俭缓,被類中所有對象共享克伊,靜態(tài)變量被分配在方法區(qū),被所有線程共享华坦。
  • 靜態(tài)代碼塊愿吹,靜態(tài)代碼在非靜態(tài)代碼執(zhí)行之前執(zhí)行,且不管改類創(chuàng)建多少對象惜姐,靜態(tài)代碼只執(zhí)行一次犁跪。
  • 靜態(tài)內(nèi)部類椿息,和非靜態(tài)內(nèi)部類最大的區(qū)別在于,非靜態(tài)內(nèi)部類在編譯后會隱含地保存著一個指向創(chuàng)建他的外部類的引用坷衍,而靜態(tài)內(nèi)部類沒有這個引用寝优。經(jīng)常這里會問到內(nèi)存泄露的問題。
為什么static方法中不能使用this和super枫耳?

static修飾靜態(tài)方法是屬于類的乏矾;而this指向當(dāng)前對象,super代表父類對象引用迁杨;靜態(tài)方法屬于類钻心,而this、super針對對象铅协。同樣的問題還有:為什么不能在靜態(tài)方法內(nèi)調(diào)用外部類的非靜態(tài)成員捷沸?一樣的答案。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末狐史,一起剝皮案震驚了整個濱河市痒给,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌预皇,老刑警劉巖侈玄,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吟温,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)突颊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門鲁豪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人律秃,你說我怎么就攤上這事爬橡。” “怎么了棒动?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵糙申,是天一觀的道長。 經(jīng)常有香客問我船惨,道長柜裸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任粱锐,我火速辦了婚禮疙挺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘怜浅。我一直安慰自己铐然,他們只是感情好蔬崩,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著搀暑,像睡著了一般沥阳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上自点,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天沪袭,我揣著相機(jī)與錄音,去河邊找鬼樟氢。 笑死冈绊,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的埠啃。 我是一名探鬼主播死宣,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼碴开!你這毒婦竟也來了毅该?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤潦牛,失蹤者是張志新(化名)和其女友劉穎眶掌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體巴碗,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡朴爬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了橡淆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片召噩。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖逸爵,靈堂內(nèi)的尸體忽然破棺而出具滴,到底是詐尸還是另有隱情,我是刑警寧澤师倔,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布构韵,位于F島的核電站,受9級特大地震影響趋艘,放射性物質(zhì)發(fā)生泄漏疲恢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一致稀、第九天 我趴在偏房一處隱蔽的房頂上張望冈闭。 院中可真熱鬧,春花似錦抖单、人聲如沸萎攒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耍休。三九已至刃永,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間羊精,已是汗流浹背斯够。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留喧锦,地道東北人读规。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像燃少,于是被迫代替她去往敵國和親束亏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 一:java概述:1阵具,JDK:Java Development Kit碍遍,java的開發(fā)和運行環(huán)境,java的開發(fā)工...
    ZaneInTheSun閱讀 2,650評論 0 11
  • 九種基本數(shù)據(jù)類型的大小阳液,以及他們的封裝類怕敬。(1)九種基本數(shù)據(jù)類型和封裝類 (2)自動裝箱和自動拆箱 什么是自動裝箱...
    關(guān)瑋琳linSir閱讀 1,884評論 0 47
  • 1.java中==和equals和hashCode的區(qū)別 1)==若是基本數(shù)據(jù)類型比較,是比較值帘皿,若是引用類型东跪,則...
    Fitz_e74a閱讀 4,464評論 1 1
  • 1. 面向?qū)ο蠛兔嫦蜻^程的區(qū)別 面向過程 優(yōu)點:性能比面向?qū)ο蟾呷秉c:消耗資源比面向過程多,且不易維護(hù)矮烹、復(fù)用越庇、擴(kuò)展...
    驍君閱讀 330評論 0 0
  • 1. 面向?qū)ο笈c面向過程的區(qū)別 面向過程: 面向過程性能比面向?qū)ο蟾撸驗轭悓ο笳{(diào)用需要實例化奉狈,開銷比較大,比較消...
    煩人的膽小鬼閱讀 194評論 0 1