最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

面試阿里字節(jié)99%會(huì)被問(wèn)到Java類(lèi)加載機(jī)制和類(lèi)加載器

  發(fā)布時(shí)間:2020-06-23 17:04:09   作者:前程有光   我要評(píng)論
這篇文章主要介紹了Java類(lèi)加載機(jī)制和類(lèi)加載器,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

1. 類(lèi)加載機(jī)制

所謂類(lèi)加載機(jī)制就是JVM虛擬機(jī)把Class文件加載到內(nèi)存,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn),轉(zhuǎn)換解析和初始化,形成虛擬機(jī)可以直接使用的Jav類(lèi)型,即Java.lang.Class。

2. 類(lèi)加載的過(guò)程

類(lèi)加載的過(guò)程主要有裝載(Load)、鏈接(Link)、初始化(Initialize)

2.1 裝載(Load)

類(lèi)的加載指的是將類(lèi)的.class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中,將其放在運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi),然后在堆區(qū)創(chuàng)建一個(gè)java.lang.Class對(duì)象,用來(lái)封裝類(lèi)在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)。類(lèi)的加載的最終產(chǎn)品是位于堆區(qū)中的Class對(duì)象,Class對(duì)象封裝了類(lèi)在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu),并且向Java程序員提供了訪(fǎng)問(wèn)方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)的接口。

類(lèi)加載器并不需要等到某個(gè)類(lèi)被“首次主動(dòng)使用”時(shí)再加載它,JVM規(guī)范允許類(lèi)加載器在預(yù)料某個(gè)類(lèi)將要被使用時(shí)就預(yù)先加載它,如果在預(yù)先加載的過(guò)程中遇到了.class文件缺失或存在錯(cuò)誤,類(lèi)加載器必須在程序首次主動(dòng)使用該類(lèi)時(shí)才報(bào)告錯(cuò)誤(LinkageError錯(cuò)誤)如果這個(gè)類(lèi)一直沒(méi)有被程序主動(dòng)使用,那么類(lèi)加載器就不會(huì)報(bào)告錯(cuò)誤。

加載.class文件的方式

  • 從本地系統(tǒng)中直接加載
  • 通過(guò)網(wǎng)絡(luò)下載.class文件
  • 從zip,jar等歸檔文件中加載.class文件
  • 從專(zhuān)有數(shù)據(jù)庫(kù)中提取.class文件
  • 將Java源文件動(dòng)態(tài)編譯為.class文件

2.2 鏈接(Link)

鏈接這一過(guò)程又可以分為驗(yàn)證(Validate)、準(zhǔn)備(Prepare)、解析(Resolve)三個(gè)階段

驗(yàn)證(Validate)

保證被加載類(lèi)的正確性。其主要包括四種驗(yàn)證,文件格式驗(yàn)證,元數(shù)據(jù)驗(yàn)證,字節(jié)碼驗(yàn)證,符號(hào)引用驗(yàn)證。

準(zhǔn)備(Prepare)

為類(lèi)的靜態(tài)變量分配內(nèi)存,并將其初始化為默認(rèn)值

準(zhǔn)備階段是正式為類(lèi)變量分配內(nèi)存并設(shè)置類(lèi)變量初始值的階段,這些內(nèi)存都將在方法區(qū)中分配。對(duì)于該階段有以下幾點(diǎn)需要注意

這時(shí)候進(jìn)行內(nèi)存分配的僅包括類(lèi)變量(static),而不包括實(shí)例變量,實(shí)例變量會(huì)在對(duì)象實(shí)例化時(shí)隨著對(duì)象一塊分配在Java堆中。

這里所設(shè)置的初始值通常情況下是數(shù)據(jù)類(lèi)型默認(rèn)的零值(如0、0L、null、false等),而不是被在Java代碼中被顯式地賦予的值。

假設(shè)一個(gè)類(lèi)變量的定義為:public static int value = 3;

那么變量value在準(zhǔn)備階段過(guò)后的初始值為0,而不是3,因?yàn)檫@時(shí)候尚未開(kāi)始執(zhí)行任何Java方法,而把value賦值為3的putstatic指令是在程序編譯后,存放于類(lèi)構(gòu)造器()方法之中的,所以把value賦值為3的動(dòng)作將在初始化階段才會(huì)執(zhí)行。

這里還需要注意以下幾點(diǎn)

對(duì)基本數(shù)據(jù)類(lèi)型來(lái)說(shuō),對(duì)于類(lèi)變量(static)和全局變量,如果不顯式地對(duì)其賦值而直接使用,則系統(tǒng)會(huì)為其賦予默認(rèn)的零值,而對(duì)于局部變量來(lái)說(shuō),在使用前必須顯式地為其賦值,否則編譯時(shí)不通過(guò)。

對(duì)于同時(shí)被static和final修飾的常量,必須在聲明的時(shí)候就為其顯式地賦值,否則編譯時(shí)不通過(guò);而只被final修飾的常量則既可以在聲明時(shí)顯式地為其賦值,也可以在類(lèi)初始化時(shí)顯式地為其賦值,總之,在使用前必須為其顯式地賦值,系統(tǒng)不會(huì)為其賦予默認(rèn)零值。

對(duì)于引用數(shù)據(jù)類(lèi)型reference來(lái)說(shuō),如數(shù)組引用、對(duì)象引用等,如果沒(méi)有對(duì)其進(jìn)行顯式地賦值而直接使用,系統(tǒng)都會(huì)為其賦予默認(rèn)的零值,即null。

如果在數(shù)組初始化時(shí)沒(méi)有對(duì)數(shù)組中的各元素賦值,那么其中的元素將根據(jù)對(duì)應(yīng)的數(shù)據(jù)類(lèi)型而被賦予默認(rèn)的零值

如果類(lèi)字段的字段屬性表中存在ConstantValue屬性,即同時(shí)被final和static修飾,那么在準(zhǔn)備階段變量value就會(huì)被初始化為ConstValue屬性所指定的值。假設(shè)上面的類(lèi)變量value被定義為: public static final int value = 3;,編譯時(shí)Javac將會(huì)為value生成ConstantValue屬性,在準(zhǔn)備階段虛擬機(jī)就會(huì)根據(jù)ConstantValue的設(shè)置將value賦值為3。我們可以理解為static final常量在編譯期就將其結(jié)果放入了調(diào)用它的類(lèi)的常量池中

解析(Resolve)

解析階段是虛擬機(jī)將常量池內(nèi)的符號(hào)引用替換為直接引用的過(guò)程。符號(hào)引用就是一組符號(hào)來(lái)描述目標(biāo),可以是任何字面量。直接引用就是直接指向目標(biāo)的指針、相對(duì)偏移量或一個(gè)間接定位到目標(biāo)的句柄。

2.3 初始化

對(duì)類(lèi)的靜態(tài)變量,靜態(tài)代碼塊執(zhí)行初始化操作。準(zhǔn)備階段和初始化階段看似有點(diǎn)矛盾,其實(shí)是不矛盾的,如果類(lèi)中有語(yǔ)句:private static int a = 10,它的執(zhí)行過(guò)程是這樣的,首先字節(jié)碼文件被加載到內(nèi)存后,先進(jìn)行鏈接的驗(yàn)證這一步驟,驗(yàn)證通過(guò)后準(zhǔn)備階段,給a分配內(nèi)存,因?yàn)樽兞縜是static的,所以此時(shí)a等于int類(lèi)型的默認(rèn)初始值0,即a=0,然后到解析,到初始化這一步驟時(shí),才把a(bǔ)的真正的值10賦給a,此時(shí)a=10。

JVM負(fù)責(zé)對(duì)類(lèi)進(jìn)行初始化,主要對(duì)類(lèi)變量進(jìn)行初始化。在Java中對(duì)類(lèi)變量進(jìn)行初始值設(shè)定有兩種方式:

聲明類(lèi)變量是指定初始值,也就是直接給類(lèi)別量一個(gè)值

使用靜態(tài)代碼塊為類(lèi)變量指定初始值

初始化,主要是執(zhí)行類(lèi)的類(lèi)構(gòu)造器< clinit>()方法,JVM會(huì)將類(lèi)中的靜態(tài)代碼塊和靜態(tài)變量的賦值語(yǔ)句放在該方法里面。

JVM初始化步驟

1、假如這個(gè)類(lèi)還沒(méi)有被加載和鏈接,則程序先加載并鏈接該類(lèi)

2、假如該類(lèi)的直接父類(lèi)還沒(méi)有被初始化,則先初始化其直接父類(lèi)

3、假如類(lèi)中有初始化語(yǔ)句,則系統(tǒng)依次執(zhí)行這些初始化語(yǔ)句

類(lèi)初始化時(shí)機(jī):只有當(dāng)對(duì)類(lèi)的主動(dòng)使用的時(shí)候才會(huì)導(dǎo)致類(lèi)的初始化,類(lèi)的主動(dòng)使用包括以下六種:

– 創(chuàng)建類(lèi)的實(shí)例,也就是new的方式

– 訪(fǎng)問(wèn)某個(gè)類(lèi)或接口的靜態(tài)變量,或者對(duì)該靜態(tài)變量賦值

– 調(diào)用類(lèi)的靜態(tài)方法

– 反射(如Class.forName(“com.shengsiyuan.Test”))

– 初始化某個(gè)類(lèi)的子類(lèi),則其父類(lèi)也會(huì)被初始化

– Java虛擬機(jī)啟動(dòng)時(shí)被標(biāo)明為啟動(dòng)類(lèi)的類(lèi)(Java Test),直接使用java.exe命令來(lái)運(yùn)行某個(gè)主類(lèi)

3. clinit方法

類(lèi)初始化方法clinit:JVM通過(guò)Classload進(jìn)行類(lèi)型加載時(shí),如果在加載時(shí)需要進(jìn)行類(lèi)的初始化操作時(shí),則會(huì)調(diào)用類(lèi)型、的初始化方法。 clinit方法是由編譯器自動(dòng)收集類(lèi)中的所有類(lèi)變量的賦值動(dòng)作和靜態(tài)語(yǔ)句塊中的語(yǔ)句合并產(chǎn)生的,編譯器收集的順序是由語(yǔ)句在源文件中出現(xiàn)的順序所決定的,靜態(tài)語(yǔ)句塊中只能訪(fǎng)問(wèn)到定義在靜態(tài)語(yǔ)句塊之前的變量,定義在它之后的變量,在前面的靜態(tài)語(yǔ)句中可以賦值,但是不能訪(fǎng)問(wèn)。

clinit方法對(duì)于類(lèi)或接口來(lái)說(shuō)并不是必須的,如果一個(gè)類(lèi)中沒(méi)有靜態(tài)語(yǔ)句塊,也沒(méi)有對(duì)類(lèi)變量的賦值操作,那么編譯器可以不為這個(gè)類(lèi)生成clinit方法。

接口中不能使用靜態(tài)語(yǔ)句塊,但仍然有類(lèi)變量(final static)初始化的賦值操作,因此接口與類(lèi)一樣會(huì)生成clinit方法。但是接口魚(yú)類(lèi)不同的是:執(zhí)行接口的clinit方法不需要先執(zhí)行父接口的clinit方法,只有當(dāng)父接口中定義的變量被使用時(shí),父接口才會(huì)被初始化。另外,接口的實(shí)現(xiàn)類(lèi)在初始化時(shí)也一樣不會(huì)執(zhí)行接口的clinit方法。

虛擬機(jī)會(huì)保證一個(gè)類(lèi)的clinit方法在多線(xiàn)程環(huán)境中被正確地加鎖和同步,如果多個(gè)線(xiàn)程同時(shí)去初始化一個(gè)類(lèi),那么只會(huì)有一個(gè)線(xiàn)程去執(zhí)行這個(gè)類(lèi)的clinit方法,其他線(xiàn)程都需要阻塞等待,直到活動(dòng)線(xiàn)程執(zhí)行clinit方法完畢。如果在一個(gè)類(lèi)的clinit方法中有耗時(shí)很長(zhǎng)的操作,那就可能造成多個(gè)線(xiàn)程阻塞,在實(shí)際應(yīng)用中這種阻塞往往是很隱蔽的。

說(shuō)到 clinit方法,就不得不說(shuō)一下對(duì)象實(shí)例化方法init。

對(duì)象實(shí)例化方法init:Java對(duì)象在被創(chuàng)建時(shí),會(huì)進(jìn)行實(shí)例化操作,給成員變量賦值。該部分操作封裝在init方法中,并且子類(lèi)的init方法中會(huì)首先對(duì)父類(lèi)init方法的調(diào)用。

clinit 方法和init 方法的區(qū)別

init和clinit方法執(zhí)行時(shí)機(jī)不同

init是對(duì)象構(gòu)造器方法,也就是說(shuō)在程序執(zhí)行new 一個(gè)對(duì)象調(diào)用該對(duì)象類(lèi)的 constructor 方法時(shí)才會(huì)執(zhí)行init方法,而clinit是類(lèi)構(gòu)造器方法,也就是在jvm進(jìn)行類(lèi)加載—–驗(yàn)證—-解析—–初始化,中的初始化階段jvm會(huì)調(diào)用clinit方法。

init和clinit方法執(zhí)行目的不同

init是instance實(shí)例構(gòu)造器,對(duì)非靜態(tài)變量解析初始化,而clinit是class類(lèi)構(gòu)造器對(duì)靜態(tài)變量,靜態(tài)代碼塊進(jìn)行初始化

clinit 和init方法的數(shù)量不同

編譯器最多只為一個(gè)類(lèi)生成一個(gè)clinit方法,如果類(lèi)中沒(méi)有靜態(tài)成員或者代碼塊的話(huà),就不有clint方法。而init方法,類(lèi)中一個(gè)構(gòu)造函數(shù)就對(duì)應(yīng)一個(gè)init方法

4. 類(lèi)加載器

類(lèi)加載器負(fù)責(zé)加載所有的類(lèi),其為所有被載入內(nèi)存中的類(lèi)生成一個(gè)java.lang.Class實(shí)例對(duì)象。一旦一個(gè)類(lèi)被加載如JVM中,同一個(gè)類(lèi)就不會(huì)被再次載入了。正如一個(gè)對(duì)象有一個(gè)唯一的標(biāo)識(shí)一樣,一個(gè)載入JVM的類(lèi)也有一個(gè)唯一的標(biāo)識(shí)。在Java中,一個(gè)類(lèi)用其全限定類(lèi)名(包括包名和類(lèi)名)作為標(biāo)識(shí);但在JVM中,一個(gè)類(lèi)用其全限定類(lèi)名和其類(lèi)加載器作為其唯一標(biāo)識(shí)。例如,如果在pg的包中有一個(gè)名為Person的類(lèi),被類(lèi)加載器ClassLoader的實(shí)例kl負(fù)責(zé)加載,則該P(yáng)erson類(lèi)對(duì)應(yīng)的Class對(duì)象在JVM中表示為(Person.pg.kl)。這意味著兩個(gè)類(lèi)加載器加載的同名類(lèi):(Person.pg.kl)和(Person.pg.kl2)是不同的、它們所加載的類(lèi)也是完全不同、互不兼容的。

JVM預(yù)定義有三種類(lèi)加載器,當(dāng)一個(gè) JVM啟動(dòng)的時(shí)候,Java開(kāi)始使用如下三種類(lèi)加載器:

啟動(dòng)類(lèi)加載器(Bootstrap ClassLoader):負(fù)責(zé)加載存放在JDKjrelib(JDK代表JDK的安裝目錄,下同)下,或被-Xbootclasspath參數(shù)指定的路徑中的,并且能被虛擬機(jī)識(shí)別的類(lèi)庫(kù)(如rt.jar,所有的java.*開(kāi)頭的類(lèi)均被Bootstrap ClassLoader加載)。啟動(dòng)類(lèi)加載器是由C++實(shí)現(xiàn)的,沒(méi)有對(duì)應(yīng)的Java對(duì)象,因此在Java中只能用null代替。

擴(kuò)展類(lèi)加載器(Extension ClassLoader):負(fù)責(zé)加載java平臺(tái)中擴(kuò)展功能的一些jar包,包括JDK/jre/lib/*.jar 或 -Djava.ext.dirs指定目錄下的jar包。,開(kāi)發(fā)者可以直接使用擴(kuò)展類(lèi)加載器。

應(yīng)用程序類(lèi)加載器(Application ClassLoader):負(fù)責(zé)加載用戶(hù)類(lèi)路徑(ClassPath)所指定的類(lèi),開(kāi)發(fā)者可以直接使用該類(lèi)加載器,如果應(yīng)用程序中沒(méi)有自定義過(guò)自己的類(lèi)加載器,一般情況下這個(gè)就是程序中默認(rèn)的類(lèi)加載器。

自定義類(lèi)加載器 Custom ClassLoader: 通過(guò)繼承java.lang.ClassLoader根據(jù)自身需要自定義ClassLoader,如tomcat、jboss都會(huì)根據(jù)j2ee規(guī)范自行實(shí)現(xiàn)ClassLoader。

5. 雙親委派模型

幾種類(lèi)加載器的層次關(guān)系如下圖所示

這種層次關(guān)系稱(chēng)為類(lèi)加載器的雙親委派模型。我們把每一層上面的類(lèi)加載器叫做當(dāng)前層類(lèi)加載器的父加載器,當(dāng)然,它們之間的父子關(guān)系并不是通過(guò)繼承關(guān)系來(lái)實(shí)現(xiàn)的,而是使用組合關(guān)系來(lái)復(fù)用父加載器中的代碼。該模型在JDK1.2期間被引入并廣泛應(yīng)用于之后幾乎所有的Java程序中,但它并不是一個(gè)強(qiáng)制性的約束模型,而是Java設(shè)計(jì)者們推薦給開(kāi)發(fā)者的一種類(lèi)的加載器實(shí)現(xiàn)方式。

雙親委派模型的工作流程是:如果一個(gè)類(lèi)加載器收到了類(lèi)加載的請(qǐng)求,它首先不會(huì)自己去嘗試加載這個(gè)類(lèi),而是把請(qǐng)求委托給父加載器去完成,依次向上,因此,所有的類(lèi)加載請(qǐng)求最終都應(yīng)該被傳遞到頂層的啟動(dòng)類(lèi)加載器中,只有當(dāng)父加載器在它的搜索范圍中沒(méi)有找到所需的類(lèi)時(shí),即無(wú)法完成該加載,子加載器才會(huì)嘗試自己去加載該類(lèi)。

雙親委派機(jī)制的優(yōu)勢(shì):采用雙親委派模式的是好處是Java類(lèi)隨著它的類(lèi)加載器一起具備了一種帶有優(yōu)先級(jí)的層次關(guān)系,通過(guò)這種層級(jí)關(guān)可以避免類(lèi)的重復(fù)加載,當(dāng)父親已經(jīng)加載了該類(lèi)時(shí),就沒(méi)有必要子ClassLoader再加載一次。其次是考慮到安全因素,java核心api中定義類(lèi)型不會(huì)被隨意替換,假設(shè)通過(guò)網(wǎng)絡(luò)傳遞一個(gè)名為java.lang.Integer的類(lèi),通過(guò)雙親委托模式傳遞到啟動(dòng)類(lèi)加載器,而啟動(dòng)類(lèi)加載器在核心Java API發(fā)現(xiàn)這個(gè)名字的類(lèi),發(fā)現(xiàn)該類(lèi)已被加載,并不會(huì)重新加載網(wǎng)絡(luò)傳遞的過(guò)來(lái)的java.lang.Integer,而直接返回已加載過(guò)的Integer.class,這樣便可以防止核心API庫(kù)被隨意篡改。

到此這篇關(guān)于面試阿里字節(jié)99%會(huì)被問(wèn)到Java類(lèi)加載機(jī)制和類(lèi)加載器的文章就介紹到這了,更多相關(guān)Java類(lèi)加載機(jī)制和類(lèi)加載器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!

相關(guān)文章

  • 程序員面試的幾個(gè)小技巧

    這篇文章主要介紹了程序員面試的幾個(gè)小技巧,在平時(shí)面試的時(shí)候,除了實(shí)打?qū)嵉募寄苓€需要更多的技巧,雙管齊下才能贏得更大的勝算,技能方面就不多說(shuō)了,下面來(lái)分享幾個(gè)面試
    2023-04-23
  • AQS底層原理連環(huán)相扣系列鎖面試題分析

    面試中,問(wèn)鎖主要是兩方面:鎖的日常使用場(chǎng)景 + 鎖原理,鎖的日常使用場(chǎng)景主要考察對(duì)鎖 API 的使用熟練度,看看你是否真的使用過(guò)這些 API,而不是紙上談兵,鎖原理主要就是
    2022-05-19
  • Mybatis常見(jiàn)面試題詳細(xì)總結(jié)

    這篇文章主要介紹了Mybatis常見(jiàn)面試題詳細(xì)總結(jié),通過(guò)總結(jié)列舉大量的mybatis面試常見(jiàn)題目供給大家參考,希望對(duì)大家有所幫助
    2021-08-24
  • 2020Java后端開(kāi)發(fā)面試題總結(jié)(春招+秋招+社招)

    這篇文章主要介紹了2020Java后端開(kāi)發(fā)面試題總結(jié)(春招+秋招+社招),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-18
  • MySQL數(shù)據(jù)庫(kù)選擇題小結(jié)

    這篇文章主要介紹了MySQL數(shù)據(jù)庫(kù)選擇題小結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-07
  • 30道有趣的JVM面試題(小結(jié))

    這篇文章主要介紹了30道有趣的JVM面試題(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-26
  • Python面試題爬蟲(chóng)篇小結(jié)(附答案)

    這篇文章主要介紹了Python面試題爬蟲(chóng)篇小結(jié)(附答案),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-28
  • 還不理解B樹(shù)和B+樹(shù),那就看看這篇文章吧

    這篇文章主要介紹了還不理解B樹(shù)和B+樹(shù),那就看看這篇文章吧,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一
    2020-09-10
  • Java面試通關(guān)要點(diǎn)匯總(備戰(zhàn)秋招)

    這篇文章主要介紹了Java面試通關(guān)要點(diǎn)匯總(備戰(zhàn)秋招),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-08
  • 10道JVM常見(jiàn)面試題解析(附答案)

    這篇文章主要介紹了10道JVM常見(jiàn)面試題解析(附答案),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)
    2020-09-04

最新評(píng)論

内乡县| 莒南县| 阳江市| 东乌珠穆沁旗| 肥西县| 米脂县| 绿春县| 长顺县| 介休市| 静安区| 醴陵市| 营口市| 柘城县| 怀来县| 西宁市| 霍林郭勒市| 赤壁市| 遵义市| 奈曼旗| 河津市| 武胜县| 孟州市| 辽中县| 卢氏县| 东乡县| 梁山县| 奉新县| 南京市| 本溪市| 巨野县| 乐东| 无锡市| 当雄县| 中卫市| 平顶山市| 通州市| 中山市| 忻城县| 九龙县| 耒阳市| 上饶县|