李克強:進一步支持新能源汽車產業,要推動五項措施

國務院總理李克強2月24日主持召開國務院常務會議,確定進一步支持新能源汽車產業的措施,以結構優化推動綠色發展。

會議指出,發展新能源汽車,推動產業邁向中高端,有利於保護和改善環境,是培育新動能的重要抓手、發展新經濟的重要內容。近兩年來,在國家政策引導和各方努力下,中國新能源汽車在研發推廣、技術水準等方面取得明顯成效,產銷快速增長。下一步,要堅持市場導向和創新驅動,依託大眾創業、萬眾創新,努力攻克核心技術,打破瓶頸制約,加速新能源汽車發展步伐。

一是加快實現動力電池革命性突破。推動大中小企業、高校、科研院所等組建協同攻關、開放共用的動力電池創新平臺,在關鍵材料、電池系統等共性、基礎技術研發上集中發力。中央財政採取以獎代補方式,根據動力電池性能、銷量等指標對企業給予獎勵。加大對動力電池數位化製造成套裝備的支援。

二是加快充電基礎設施建設。明確地方政府、業主、開發商、物業和電網企業等責權利,推動落實住宅社區和黨政機關、企事業單位、機場景區及其他社會停車場等建設充電設施的要求。利用中央預算內投資和配電網專項金融債等支持各地充電設施建設,鼓勵地方建立以充電量為基準的獎勵補貼政策,減免充電服務費用。

三是擴大城市公交、計程車、環衛、物流等領域新能源汽車應用比例。中央國家機關、新能源汽車推廣應用城市的政府部門及公共機構購買新能源汽車占當年配備更新車輛總量的比例,要提高到50%以上。

四是提升新能源汽車整車品質。完善准入標準,加強品質安全監管,發展新能源汽車+物聯網,強化生產企業對新能源汽車的安全監控、動態檢查,建立懲罰性賠償和市場退出等機制。

五是完善財政補貼等扶持政策,督促落實不得對新能源汽車限行限購的要求,破除地方保護,打擊“騙補”行為。建立合理投資回報機制,鼓勵社會資本進入充電設施建設運營、整車租賃、電池回收利用等服務領域。國務院新能源汽車協調機制及其辦公機構要履行好協調職責。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

印尼最老說故事壁畫 考古學家和採礦伐木業賽跑

摘錄自2020年2月26日自由時報報導

外界近期才知道印尼蘇拉威西省一座礦場藏有據信是世上最古老的說故事、具象壁畫。然而壁畫表面到處都有脫落,考古學家正與採礦和伐木業賽跑,尋找附近尚未出土的壁畫。

澳洲格里菲斯大學(Griffith University)的考古學團隊去年12月11日在「自然」(Nature)期刊發表論文指出,他們利用定年技術研究發現,蘇拉威西(Sulawesi)一處石灰岩洞裡一幅描繪半獸半人的狩獵者揮舞長矛、繩索,追捕野豬和侏儒水牛的壁畫,至少可追溯至4萬3900年前的舊石器時代晚期。

駐雅加達美籍記者瓦拉古(Krithika Varagur)在印尼考古學家布迪安多(Budianto Hakim)的陪同下,去年耶誕節前探訪了這座洞穴。她20日在「經濟學人」雜誌姐妹刊物「1843」發表文章,憂心開發礦場的伐木業以及採礦活動對環境造成的改變,會影響這幅壁畫及其他尚未出土壁畫的保存。

瓦拉古指出,洞穴位於多納沙(Tonasa)水泥公司礦場內,多納沙在1984年取得採礦權。壁畫被發現後,多納沙與蘇拉威西文化資產保存中心簽訂契約,將洞穴周邊封鎖起來,以保護壁畫;並承諾如發現新遺跡,也會向資產保存中心報告。但多納沙仍持續開採活動,要參觀洞穴也須先取得多納沙同意。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

尚比亞乾旱飢荒 就學發電全受影響

摘錄自2020年3月3日公視報導

非洲中南部國家尚比亞遭逢嚴重乾旱,數百萬人口面臨飢荒威脅,也連帶影響就學出席率、水力發電和經濟成長。

尚比亞南部正遭逢嚴重乾旱,國際人道組織紛紛送上玉蜀黍和豆子等救援物資,食物短缺也連帶影響了就學狀況。志工教師卡優教尼就說:「我的班上有70名學生,因為飢荒的關係學生曠課,像今天70個學生,只有30個來上課。」

雖然最近有下雨,但別被短暫的綠意盎然給騙了,因為這裡的作物已經好幾年沒有豐收。根據聯合國世界糧食計劃署,非洲南部共有約4500萬人口面臨飢荒危機。四個多小時車程外的卡瑞巴水力發電廠,負責尚比亞全國40%的供電。然而,因為水量不足,渦輪機根本無法產生足夠的電力。

卡瑞巴水力發電廠代理經理喬佛瑞表示:「2020年我們目標發電275千瓩,這是卡瑞巴北岸發電廠,最大發電量的25%,因為水位過低。」

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

中國鬆口承認蝗蟲可能從印巴入侵 急發防蝗緊急通知

摘錄自2020年3月3日中央廣播電台報導

源自東非的蝗災肆虐南亞逐漸向中國逼近,早先中國農業農村部與中國科學院院士康樂才對外表示這波蝗災影響中國可能性不大,不過中國國家林草局2日卻發出緊急通知,明白指出沙漠蝗蟲可能從巴基斯坦和印度沿青藏高原河谷地帶入侵西藏、雲南、新疆等地,坦言存在造成危害的風險,要求確實做好防控。

武漢肺炎(COVID-19)疫情還在中國持續流竄,但源自於非洲的蝗災卻已經蔓延到巴基斯坦、印度等地,早先聯合國糧農組織(Food and Agriculture Organization, FAO)透露,這波蝗災有可能延續至2020年6月,屆時蝗群規模可能比目前大出500倍,呼籲全球戒備,但中國農業單位認為,中國蝗蟲監測預警和防治能力提升,防蝗藥械儲備充足,大面積爆發蝗災的風險很低。不過中國國家林草局2日則是發出一份緊急通知,公開呼籲民眾做好蝗災的防範。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※帶您來看台北網站建置台北網頁設計,各種案例分享

小三通物流營運型態?

※快速運回,大陸空運推薦?

英國將在公共道理上開測無人駕駛卡車車隊

Google已經測試無人駕駛小汽車多年,而這項技術的下一階段,則是無人駕駛貨車。由於擺脫了傳統貨車駕駛員所必須的睡眠休息時間,無人駕駛卡車將能夠讓長途運輸變得比以往更快。

據悉,英國將於今年晚些時候開測無人駕駛卡車車隊,不過它不僅僅是為了提升物流的速度,還有望減輕道路的擁塞狀況。

在不久的將來,人們將能夠在M6高速路上見到高達10輛的無人駕駛貨車車隊。此外,儘管測試是在公共道路上進行,但有關方面會盡可能地將影響和潛在問題降到最低。

當然,這並不是我們首次見到無人駕駛貨車車隊的測試。此前,戴姆勒也曾在德國進行過類似的試驗,只是它仍然需要一個人類駕駛員作為後備。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

奔馳下一代汽車將棄用特斯拉電動傳動系統 採用自家技術

戴姆勒電動汽車主管哈拉爾德•克勒格爾(Harald Kroeger)在接受德國媒體採訪時說,為了開發自有傳動系統和電池技術,奔馳已經投資了5.5億美元,下一代B級Electric Drive電動汽車不會使用特斯拉傳動系統。

奔馳這樣做合情合理。2014年年末時,奔馳基本上已經清空了特斯拉持股。在2014年的年報中特斯拉也說B級車研發合作已經基本完成。到了2015年年底,特斯拉已經銷售10萬輛電動汽車。以前特斯拉是矽谷新崛起的明星企業,一些大型汽車公司有興趣與它合作,現在汽車公司已經將特斯拉當成了競爭對手。比如豐田,在特斯拉成立之初,豐田也曾參與投資,特斯拉還為豐田電動版RAV4提供傳動系統。

那時的特斯拉還很年輕,它還沒有推出Model S轎車,如果能與大型汽車商合作對公司的發展無疑是有利的。特斯拉需要增加營收,只有有了營收,公司才有可能轉變為主流汽車製造商。另外,在公司沒有上市之前,它需要吸引早期投資者來支援自己。今天的特斯拉已經完全不同了,Model S大獲成功,Model X剛剛開始向用戶交貨。本月晚些時候Model 3也將上市,這是一款低價電動汽車。可以說現在的特斯拉已經是一家規模雖小但是卻很成熟的電動汽車製造商了。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※帶您來看台北網站建置台北網頁設計,各種案例分享

小三通物流營運型態?

※快速運回,大陸空運推薦?

【集合系列】- 深入淺出分析LinkedHashMap

一、摘要

在集合系列的第一章,咱們了解到,Map的實現類有HashMap、LinkedHashMap、TreeMap、IdentityHashMap、WeakHashMap、Hashtable、Properties等等。

本文主要從數據結構和算法層面,探討LinkedHashMap的實現。

二、簡介

LinkedHashMap可以認為是HashMap+LinkedList,它既使用HashMap操作數據結構,又使用LinkedList維護插入元素的先後順序,內部採用雙向鏈表(doubly-linked list)的形式將所有元素( entry )連接起來。

LinkedHashMap繼承了HashMap,允許放入key為null的元素,也允許插入value為null的元素。從名字上可以看出該容器是LinkedList和HashMap的混合體,也就是說它同時滿足HashMap和LinkedList的某些特性,可將LinkedHashMap看作採用Linked list增強的HashMap。

打開 LinkedHashMap 源碼,可以看到主要三個核心屬性:

public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>{

    /**雙向鏈表的頭節點*/
    transient LinkedHashMap.Entry<K,V> head;

    /**雙向鏈表的尾節點*/
    transient LinkedHashMap.Entry<K,V> tail;

    /**
      * 1、如果accessOrder為true的話,則會把訪問過的元素放在鏈表後面,放置順序是訪問的順序
      * 2、如果accessOrder為false的話,則按插入順序來遍歷
      */
      final boolean accessOrder;
}

LinkedHashMap 在初始化階段,默認按插入順序來遍歷

public LinkedHashMap() {
        super();
        accessOrder = false;
}

LinkedHashMap 採用的 Hash 算法和 HashMap 相同,不同的是,它重新定義了數組中保存的元素Entry,該Entry除了保存當前對象的引用外,還保存了其上一個元素before和下一個元素after的引用,從而在哈希表的基礎上又構成了雙向鏈接列表。

源碼如下:

static class Entry<K,V> extends HashMap.Node<K,V> {
        //before指的是鏈表前驅節點,after指的是鏈表后驅節點
        Entry<K,V> before, after;
        Entry(int hash, K key, V value, Node<K,V> next) {
            super(hash, key, value, next);
        }
}

可以直觀的看出,雙向鏈表頭部插入的數據為鏈表的入口,迭代器遍歷方向是從鏈表的頭部開始到鏈表尾部結束。

除了可以保迭代歷順序,這種結構還有一個好處:迭代LinkedHashMap時不需要像HashMap那樣遍歷整個table,而只需要直接遍歷header指向的雙向鏈表即可,也就是說LinkedHashMap的迭代時間就只跟entry的個數相關,而跟table的大小無關。

三、常用方法介紹

3.1、get方法

get方法根據指定的key值返回對應的value。該方法跟HashMap.get()方法的流程幾乎完全一樣,默認按照插入順序遍歷。

public V get(Object key) {
        Node<K,V> e;
        if ((e = getNode(hash(key), key)) == null)
            return null;
        if (accessOrder)
            afterNodeAccess(e);
        return e.value;
}

如果accessOrdertrue的話,會把訪問過的元素放在鏈表後面,放置順序是訪問的順序

void afterNodeAccess(Node<K,V> e) { // move node to last
        LinkedHashMap.Entry<K,V> last;
        if (accessOrder && (last = tail) != e) {
            LinkedHashMap.Entry<K,V> p =
                (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
            p.after = null;
            if (b == null)
                head = a;
            else
                b.after = a;
            if (a != null)
                a.before = b;
            else
                last = b;
            if (last == null)
                head = p;
            else {
                p.before = last;
                last.after = p;
            }
            tail = p;
            ++modCount;
        }
}

測試用例:

public static void main(String[] args) {
        //accessOrder默認為false
        Map<String, String> accessOrderFalse = new LinkedHashMap<>();
        accessOrderFalse.put("1","1");
        accessOrderFalse.put("2","2");
        accessOrderFalse.put("3","3");
        accessOrderFalse.put("4","4");
        System.out.println("acessOrderFalse:"+accessOrderFalse.toString());
        
        //accessOrder設置為true
        Map<String, String> accessOrderTrue = new LinkedHashMap<>(16, 0.75f, true);
        accessOrderTrue.put("1","1");
        accessOrderTrue.put("2","2");
        accessOrderTrue.put("3","3");
        accessOrderTrue.put("4","4");
        accessOrderTrue.get("2");//獲取鍵2
        accessOrderTrue.get("3");//獲取鍵3
        System.out.println("accessOrderTrue:"+accessOrderTrue.toString());
}

輸出結果:

acessOrderFalse:{1=1, 2=2, 3=3, 4=4}
accessOrderTrue:{1=1, 4=4, 2=2, 3=3}

3.2、put方法

put(K key, V value)方法是將指定的key, value對添加到map里。該方法首先會調用HashMap的插入方法,同樣對map做一次查找,看是否包含該元素,如果已經包含則直接返回,查找過程類似於get()方法;如果沒有找到,將元素插入集合。

/**HashMap 中實現*/
public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
}

LinkedHashMap 中覆寫的方法

// LinkedHashMap 中覆寫
Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
    LinkedHashMap.Entry<K,V> p =
        new LinkedHashMap.Entry<K,V>(hash, key, value, e);
    // 將 Entry 接在雙向鏈表的尾部
    linkNodeLast(p);
    return p;
}

private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
    LinkedHashMap.Entry<K,V> last = tail;
    tail = p;
    // last 為 null,表明鏈表還未建立
    if (last == null)
        head = p;
    else {
        // 將新節點 p 接在鏈表尾部
        p.before = last;
        last.after = p;
    }
}

3.3、remove方法

remove(Object key)的作用是刪除key值對應的entry,該方法實現邏輯主要以HashMap為主,首先找到key值對應的entry,然後刪除該entry(修改鏈表的相應引用),查找過程跟get()方法類似,最後會調用 LinkedHashMap 中覆寫的方法,將其刪除!

/**HashMap 中實現*/
public V remove(Object key) {
    Node<K,V> e;
    return (e = removeNode(hash(key), key, null, false, true)) == null ?
        null : e.value;
}

final Node<K,V> removeNode(int hash, Object key, Object value,
                           boolean matchValue, boolean movable) {
    Node<K,V>[] tab; Node<K,V> p; int n, index;
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (p = tab[index = (n - 1) & hash]) != null) {
        Node<K,V> node = null, e; K k; V v;
        if (p.hash == hash &&
            ((k = p.key) == key || (key != null && key.equals(k))))
            node = p;
        else if ((e = p.next) != null) {
            if (p instanceof TreeNode) {...}
            else {
                // 遍歷單鏈表,尋找要刪除的節點,並賦值給 node 變量
                do {
                    if (e.hash == hash &&
                        ((k = e.key) == key ||
                         (key != null && key.equals(k)))) {
                        node = e;
                        break;
                    }
                    p = e;
                } while ((e = e.next) != null);
            }
        }
        if (node != null && (!matchValue || (v = node.value) == value ||
                             (value != null && value.equals(v)))) {
            if (node instanceof TreeNode) {...}
            // 將要刪除的節點從單鏈表中移除
            else if (node == p)
                tab[index] = node.next;
            else
                p.next = node.next;
            ++modCount;
            --size;
            afterNodeRemoval(node);    // 調用刪除回調方法進行後續操作
            return node;
        }
    }
    return null;
}

LinkedHashMap 中覆寫的 afterNodeRemoval 方法

void afterNodeRemoval(Node<K,V> e) { // unlink
    LinkedHashMap.Entry<K,V> p =
        (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
    // 將 p 節點的前驅后後繼引用置空
    p.before = p.after = null;
    // b 為 null,表明 p 是頭節點
    if (b == null)
        head = a;
    else
        b.after = a;
    // a 為 null,表明 p 是尾節點
    if (a == null)
        tail = b;
    else
        a.before = b;
}

四、總結

LinkedHashMap 繼承自 HashMap,所有大部分功能特性基本相同,二者唯一的區別是 LinkedHashMap 在HashMap的基礎上,採用雙向鏈表(doubly-linked list)的形式將所有 entry 連接起來,這樣是為保證元素的迭代順序跟插入順序相同。

主體部分跟HashMap完全一樣,多了header指向雙向鏈表的頭部,tail指向雙向鏈表的尾部,默認雙向鏈表的迭代順序就是entry的插入順序。

五、參考

1、JDK1.7&JDK1.8 源碼
2、

作者:炸雞可樂
出處:

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

不止面試—jvm類加載面試題詳解

面試題

帶着問題學習是最高效的,本次我們將嘗試回答以下問題:

  1. 什麼是類的加載?
  2. 哪些情況會觸發類的加載?
  3. 講一下JVM加載一個類的過程
  4. 什麼時候會為變量分配內存?
  5. JVM的類加載機制是什麼?
  6. 雙親委派機制可以打破嗎?為什麼

答案放在文章的最後,來不及看原理也可以直接跳到最後直接看答案。

深入原理

類的生命周期

類的生命周期相信大家已經耳熟能詳,就像下面這樣:

不過這東西總是背了就忘,忘了又背,就像馬什麼梅一樣,對吧?

其實理解之後,基本上就不會再忘了。

加載

加載主要做三件事:

  1. 找到類文件(通過類的全限定名來獲取定義此類的二進制字節流)
  2. 放入方法區(將這個字節流所代表的靜態存儲結構轉化為方法區的運行時數據結構)
  3. 開個入口(生成一個代表此類的java.lang.Class對象,作為訪問方法區這些數據結構的入口)

總的來講,這一步就是通過類加載器把類讀入內存。需要注意的是,第三步雖然生成了對象,但並不在堆里,而是在方法區里。

連接

連接分為三步,一般面試都比較喜歡問準備這一步。

校驗

顧名思義,檢查Class文件的字節流中包含的信息是否符合當前虛擬機的要求。

準備

這一步中將為靜態變量和靜態常量分配內存,並賦值。

需要注意的是,靜態變量只會給默認值。比如下面這個:

public static int value = 123;

此時賦給value的值是0,不是123。

靜態常量(static final修飾的)則會直接賦值。比如下面這個:

public static final int value = 123;

此時賦給value的值是123。

解析

解析階段就是jvm將常量池的符號引用替換為直接引用。

恩……啥是常量池?啥是符號引用?啥是直接引用?

常量池我們放在jvm內存結構里說。先來說下什麼是符號引用和直接引用。

符號引用和直接引用

假設有一個Worker類,包含了一個Car類的run()方法,像下面這樣:

class Worker{
    ......
    public void gotoWork(){
        car.run(); //這段代碼在Worker類中的二進製表示為符號引用        
    }
    ......
}

在解析階段之前,Worker類並不知道car.run()這個方法內存的什麼地方,於是只能用一個字符串來表示這個方法。該字符串包含了足夠的信息,比如類的信息,方法名,方法參數等,以供實際使用時可以找到相應的位置。

這個字符串就被稱為符號引用

在解析階段,jvm根據字符串的內容找到內存區域中相應的地址,然後把符號引用替換成直接指向目標的指針、句柄、偏移量等,這之後就可以直接使用了。

這些直接指向目標的指針、句柄、偏移量就被成為直接引用

初始化

類的初始化的主要工作是為靜態變量賦程序設定的初值。

還記得上面的靜態變量嗎:

public static int value = 123;

經過這一步,value的值終於是123了。

總結如下圖:

類初始化的條件

Java虛擬機規範中嚴格規定了有且只有五種情況必須對類進行初始化:

  1. 使用new字節碼指令創建類的實例,或者使用getstatic、putstatic讀取或設置一個靜態字段的值(放入常量池中的常量除外),或者調用一個靜態方法的時候,對應類必須進行過初始化。
  2. 通過java.lang.reflect包的方法對類進行反射調用的時候,如果類沒有進行過初始化,則要首先進行初始化。
  3. 當初始化一個類的時候,如果發現其父類沒有進行過初始化,則首先觸發父類初始化。
  4. 當虛擬機啟動時,用戶需要指定一個主類(包含main()方法的類),虛擬機會首先初始化這個類。
  5. 使用jdk1.7的動態語言支持時,如果一個java.lang.invoke.MethodHandle實例最後的解析結果REF_getStatic、REF_putStatic、RE_invokeStatic的方法句柄,並且這個方法句柄對應的類沒有進行初始化,則需要先觸發其初始化。

除了以上這五種情況,其他任何情況都不會觸發類的初始化。

比如下面這幾種情況就不會觸發類初始化:

  1. 通過子類調用父類的靜態字段。此時父類符合情況一,而子類不符合任何情況。所以只有父類被初始化。
  2. 通過數組來引用類,不會觸發類的初始化。因為new的是數組,而不是類。
  3. 調用類的靜態常量不會觸發類的初始化,因為靜態常量在編譯階段就會被存入調用類的常量池中,不會引用到定義常量的類。

類加載機制

類加載器

在上面咱們曾經說到,加載階段需要“通過一個類的全限定名來獲取描述此類的二進制字節流”。這件事情就是類加載器在做。

jvm自帶三種類加載器,分別是:

  1. 啟動類加載器。
  2. 擴展類加載器。
  3. 應用程序類加載器

他們的繼承關係如下圖:

雙親委派

雙親委派機制工作過程如下:

  1. 當前ClassLoader首先從自己已經加載的類中查詢是否此類已經加載,如果已經加載則直接返回原來已經加載的類。每個類加載器都有自己的加載緩存,當一個類被加載了以後就會放入緩存,等下次加載的時候就可以直接返回了。

  2.  當前classLoader的緩存中沒有找到被加載的類的時候,委託父類加載器去加載,父類加載器採用同樣的策略,首先查看自己的緩存,然後委託父類的父類去加載,一直到bootstrp ClassLoader.

  3.  當所有的父類加載器都沒有加載的時候,再由當前的類加載器加載,並將其放入它自己的緩存中,以便下次有加載請求的時候直接返回。

為啥要搞這麼複雜?自己處理不好嗎?

雙親委派的優點如下:

  1. 避免重複加載。當父親已經加載了該類的時候,就沒有必要子ClassLoader再加載一次。
  2. 為了安全。避免核心類,比如String被替換。

打破雙親委派

“雙親委派”機制只是Java推薦的機制,並不是強制的機制。

比如JDBC就打破了雙親委派機制。它通過Thread.currentThread().getContextClassLoader()得到線程上下文加載器來加載Driver實現類,從而打破了雙親委派機制。

至於為什麼,以後再說吧。

答案

現在,我們可以回答文章開頭提出的問題了。盡量在理解的基礎上回答,不需要死記硬背。

  1. 什麼是類的加載?

    JVM把通過類名獲得類的二進制流之後,把類放入方法區,並創建入口對象的過程被稱為類的加載。經過加載,類就被放到內存里了。

  2. 哪些情況會觸發類的初始化?

    類在5種情況下會被初始化:

    第一,假如這個類是入口類,他會被初始化。

    第二,使用new創建對象,或者調用類的靜態變量,類會被初始化。不過靜態常量不算。

    第三,通過反射獲取類,類會被初始化

    第四,如果子類被初始化,他的父類也會被初始化。

    第五,使用jdk1.7的動態語言支持時,調用到靜態句柄,也會被初始化。

  3. 講一下JVM加載一個類的過程

    同問題1。不過這裏也可以問下面試官是不是想問類的生命周期。如果是問類的生命周期,可以回答有”加載、連接、初始化、使用、卸載“五個階段,連接又可以分為”校驗、準備、解析“三個階段。

  4. 什麼時候會為變量分配內存?

    在準備階段為靜態變量分配內存。

  5. JVM的類加載機制是什麼?

    雙親委派機制,類加載器會先讓自己的父類來加載,父類無法加載的話,才會自己來加載。

  6. 雙親委派機制可以打破嗎?為什麼

    可以打破,比如JDBC使用線程上下文加載器打破了雙親委派機制。原因是JDBC只提供了接口,並沒有提供實現。這個問題可以再看下引用文獻的內容。

引用文獻

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※帶您來看台北網站建置台北網頁設計,各種案例分享

小三通物流營運型態?

※快速運回,大陸空運推薦?

延燒八個月 澳洲新南威爾斯省野火終於撲滅

摘錄自2020年3月10日大紀元報導

澳洲新南威爾斯省日前正式宣布,當地延燒了大約八個月、造成無數損失的野火,終於完全撲滅了。據CNN報導,新南威爾斯省的消防部門在2月13日宣布,該省所有野火已經受到控制。而現在,所有野火都已經被撲滅。

新南威爾斯鄉村消防署(NSW Rural FIre Service)在3月2日發推文說:「目前沒有在延燒中的野火。這是自2019年7月初以來的第一次。」該署還提到,這場野火持續了超過240天。這場延燒了幾個月的野火最終導致至少28人死亡,大約3,000棟房屋被毀,多達10億隻動物受到波及。

現在,在澳洲政府正式宣布野火被撲滅之後,該國將開始其災後重建的工作,他們正在討論是否應該針對高風險的地區制定重建的限制。而對於在何處和如何重建房屋而言,屋主正面臨困難的選擇。

森林
災害
生態保育
土地水文
國際新聞
澳洲
大火
澳洲野火

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

特斯拉將在蘇州成立生產基地?

作為全球最具潛力的電動車市場之一,特斯拉(Tesla)也持續傳出有在中國設置本土化生產基地的消息。日前中國流出一份文件,內容是關於蘇州召開會議討論特斯拉汽車項目入主蘇州的相關事宜,似乎代表特斯拉已選定了地點。

根據中國網路媒體《第一電動網》所獲得的資訊,蘇州相關政府部門於3月13日召開專題會議,研究協調特斯拉的汽車生產工廠成立相關事宜。通知內容如下:

經研究,市委副書記、常務副市長周偉強定於3月13日(星期天)上午9:00,在市政府1號會議室召開專題會議,研究協調特斯拉汽車項目落戶蘇州的相關事宜。會議主要有三項議程:一是請商務局通報該項目整體情況;二是請各有關地區匯報爭取該項目落地的相關意見和措施(如土地供應等方面,書面材料請帶5份至會);三是市各有關部門就推進該項目提出有關建議(項目情況見附件)。

請各地政府(管委會)、各有關部門主要領導或分管領導準時參會(可攜帶具體業務負責同志),特此通知。

據了解,特斯拉高層於3月17、18日拜訪蘇州進行實地考察,但《第一電動網》對此事進行深入訪談,包括蘇州商務局等相關人士均沒有正面回應。特斯拉近來一直被傳言將在中國尋找合資夥伴並設立工廠,也有許多中國公司主動表達合作意願,不過特斯拉對於在中國設廠一事一直沒有明確的回答。

台灣特斯拉汽車公司日前正式登記成案,特斯拉在中國的動向也值得關切。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務