Java 注解完全解析

關(guān)于注解首先引入官方文檔的一句話:Java 注解用于為 Java 代碼提供元數(shù)據(jù)。作為元數(shù)據(jù),注解不直接影響你的代碼執(zhí)行,但也有一些類(lèi)型的注解實(shí)際上可以用于這一目的。Java 注解是從 Java5 開(kāi)始添加到 Java 的。看完這句話也許你還是一臉懵逼,接下我將從注解的定義、元注解、注解屬性、自定義注解、注解解析JDK 提供的注解這幾個(gè)方面再次了解注解(Annotation)

我自己是一個(gè)從事了6年的Java全棧工程師,最近整理了一套適合2019年學(xué)習(xí)的Java\大數(shù)據(jù)資料,從基礎(chǔ)的Java、大數(shù)據(jù)面向?qū)ο蟮竭M(jìn)階的框架知識(shí)都有整理哦,可以來(lái)我的主頁(yè)免費(fèi)領(lǐng)取哦

注解的定義

日常開(kāi)發(fā)中新建Java類(lèi),我們使用class、interface比較多,而注解和它們一樣,也是一種類(lèi)的類(lèi)型,他是用的修飾符為 @interface

注解類(lèi)的寫(xiě)法最近整理了一套適合2019年學(xué)習(xí)的Java\大數(shù)據(jù)資料,從基礎(chǔ)的Java、大數(shù)據(jù)面向?qū)ο蟮竭M(jìn)階的框架知識(shí)都有整理哦,可以來(lái)我的主頁(yè)免費(fèi)領(lǐng)取哦。

我們新建一個(gè)注解MyTestAnnotation

public@interfaceMyTestAnnotation{}復(fù)制代碼

接著我們就可以在類(lèi)或者方法上作用我們剛剛新建的注解

@MyTestAnnotationpublicclasstest{@MyTestAnnotationpublicstaticvoidmain(String[] args){? }}復(fù)制代碼

以上我們只是了解了注解的寫(xiě)法,但是我們定義的注解中還沒(méi)寫(xiě)任何代碼,現(xiàn)在這個(gè)注解毫無(wú)意義,要如何使注解工作呢?接下來(lái)我們接著了解元注解。

元注解

元注解顧名思義我們可以理解為注解的注解,它是作用在注解中,方便我們使用注解實(shí)現(xiàn)想要的功能。元注解分別有@Retention、 @Target、 @Document、 @Inherited和@Repeatable(JDK1.8加入)五種。

@Retention

Retention英文意思有保留、保持的意思,它表示注解存在階段是保留在源碼(編譯期),字節(jié)碼(類(lèi)加載)或者運(yùn)行期(JVM中運(yùn)行)。在@Retention注解中使用枚舉RetentionPolicy來(lái)表示注解保留時(shí)期

@Retention(RetentionPolicy.SOURCE),注解僅存在于源碼中,在class字節(jié)碼文件中不包含

@Retention(RetentionPolicy.CLASS), 默認(rèn)的保留策略,注解會(huì)在class字節(jié)碼文件中存在,但運(yùn)行時(shí)無(wú)法獲得

@Retention(RetentionPolicy.RUNTIME), 注解會(huì)在class字節(jié)碼文件中存在,在運(yùn)行時(shí)可以通過(guò)反射獲取到

如果我們是自定義注解,則通過(guò)前面分析,我們自定義注解如果只存著源碼中或者字節(jié)碼文件中就無(wú)法發(fā)揮作用,而在運(yùn)行期間能獲取到注解才能實(shí)現(xiàn)我們目的,所以自定義注解中肯定是使用?@Retention(RetentionPolicy.RUNTIME)

@Retention(RetentionPolicy.RUNTIME)public@interfaceMyTestAnnotation {}復(fù)制代碼

@Target

Target的英文意思是目標(biāo),這也很容易理解,使用@Target元注解表示我們的注解作用的范圍就比較具體了,可以是類(lèi),方法,方法參數(shù)變量等,同樣也是通過(guò)枚舉類(lèi)ElementType表達(dá)作用類(lèi)型

@Target(ElementType.TYPE) 作用接口、類(lèi)、枚舉、注解

@Target(ElementType.FIELD) 作用屬性字段、枚舉的常量

@Target(ElementType.METHOD) 作用方法

@Target(ElementType.PARAMETER) 作用方法參數(shù)

@Target(ElementType.CONSTRUCTOR) 作用構(gòu)造函數(shù)

@Target(ElementType.LOCAL_VARIABLE)作用局部變量

@Target(ElementType.ANNOTATION_TYPE)作用于注解(@Retention注解中就使用該屬性)

@Target(ElementType.PACKAGE) 作用于包

@Target(ElementType.TYPE_PARAMETER) 作用于類(lèi)型泛型,即泛型方法、泛型類(lèi)、泛型接口 (jdk1.8加入)

@Target(ElementType.TYPE_USE) 類(lèi)型使用.可以用于標(biāo)注任意類(lèi)型除了 class (jdk1.8加入)

一般比較常用的是ElementType.TYPE類(lèi)型

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public@interfaceMyTestAnnotation {}復(fù)制代碼

@Documented

Document的英文意思是文檔。它的作用是能夠?qū)⒆⒔庵械脑匕?Javadoc 中去。

@Inherited

Inherited的英文意思是繼承,但是這個(gè)繼承和我們平時(shí)理解的繼承大同小異,一個(gè)被@Inherited注解了的注解修飾了一個(gè)父類(lèi),如果他的子類(lèi)沒(méi)有被其他注解修飾,則它的子類(lèi)也繼承了父類(lèi)的注解。

下面我們來(lái)看個(gè)@Inherited注解例子

/**自定義注解*/@Documented@Inherited@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public@interfaceMyTestAnnotation{}/**父類(lèi)標(biāo)注自定義注解*/@MyTestAnnotationpublicclassFather{}/**子類(lèi)*/publicclassSonextendsFather{}/**測(cè)試子類(lèi)獲取父類(lèi)自定義注解*/publicclasstest{? public static void main(String[] args){//獲取Son的class對(duì)象Class sonClass =Son.class;// 獲取Son類(lèi)上的注解MyTestAnnotation可以執(zhí)行成功MyTestAnnotationannotation = sonClass.getAnnotation(MyTestAnnotation.class);? }}復(fù)制代碼

@Repeatable

Repeatable的英文意思是可重復(fù)的。顧名思義說(shuō)明被這個(gè)元注解修飾的注解可以同時(shí)作用一個(gè)對(duì)象多次,但是每次作用注解又可以代表不同的含義。

下面我們看一個(gè)人玩游戲的例子

/**一個(gè)人喜歡玩游戲,他喜歡玩英雄聯(lián)盟,絕地求生,極品飛車(chē),塵埃4等,則我們需要定義一個(gè)人的注解,他屬性代表喜歡玩游戲集合,一個(gè)游戲注解,游戲?qū)傩源碛螒蛎Q(chēng)*//**玩家注解*/@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public@interfacePeople {? ? Game[] value() ;}/**游戲注解*/@Repeatable(People.class)@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public@interfaceGame {? ? String value()default"";}/**玩游戲類(lèi)*/@Game(value ="LOL")@Game(value ="PUBG")@Game(value ="NFS")@Game(value ="Dirt4")publicclassPlayGame{}復(fù)制代碼

通過(guò)上面的例子,你可能會(huì)有一個(gè)疑問(wèn),游戲注解中括號(hào)的變量是啥,其實(shí)這和游戲注解中定義的屬性對(duì)應(yīng)。接下來(lái)我們繼續(xù)學(xué)習(xí)注解的屬性。

注解的屬性

通過(guò)上一小節(jié)@Repeatable注解的例子,我們說(shuō)到注解的屬性。注解的屬性其實(shí)和類(lèi)中定義的變量有異曲同工之處,只是注解中的變量都是成員變量(屬性),并且注解中是沒(méi)有方法的,只有成員變量,變量名就是使用注解括號(hào)中對(duì)應(yīng)的參數(shù)名,變量返回值注解括號(hào)中對(duì)應(yīng)參數(shù)類(lèi)型。相信這會(huì)你應(yīng)該會(huì)對(duì)上面的例子有一個(gè)更深的認(rèn)識(shí)。而@Repeatable注解中的變量則類(lèi)型則是對(duì)應(yīng)Annotation(接口)的泛型Class。

/**注解Repeatable源碼*/@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public@interfaceRepeatable {/**? ? * Indicates thecontaining annotation typeforthe? ? * repeatable annotation type.? ? * @return thecontaining annotation type? ? */Class value();}復(fù)制代碼

注解的本質(zhì)

注解的本質(zhì)就是一個(gè)Annotation接口

/**Annotation接口源碼*/publicinterfaceAnnotation{? ? ? boolean equals(Objectobj);inthashCode();? ? ? ? Class annotationType();}復(fù)制代碼

通過(guò)以上源碼,我們知道注解本身就是Annotation接口的子接口,?也就是說(shuō)注解中其實(shí)是可以有屬性和方法,但是接口中的屬性都是static final的,對(duì)于注解來(lái)說(shuō)沒(méi)什么意義,而我們定義接口的方法就相當(dāng)于注解的屬性,也就對(duì)應(yīng)了前面說(shuō)的為什么注解只有屬性成員變量,其實(shí)他就是接口的方法,這就是為什么成員變量會(huì)有括號(hào)?,不同于接口我們可以在注解的括號(hào)中給成員變量賦值。

注解屬性類(lèi)型

注解屬性類(lèi)型可以有以下列出的類(lèi)型

1.基本數(shù)據(jù)類(lèi)型

2.String

3.枚舉類(lèi)型

4.注解類(lèi)型

5.Class類(lèi)型

6.以上類(lèi)型的一維數(shù)組類(lèi)型

注解成員變量賦值

如果注解又多個(gè)屬性,則可以在注解括號(hào)中用“,”號(hào)隔開(kāi)分別給對(duì)應(yīng)的屬性賦值,如下例子,注解在父類(lèi)中賦值屬性

@Documented@Inherited@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public@interfaceMyTestAnnotation {? ? String name()default"mao";? ? int age()default18;}@MyTestAnnotation(name ="father",age = 50)publicclassFather{}復(fù)制代碼

獲取注解屬性

前面我們說(shuō)了很多注解如何定義,放在哪,現(xiàn)在我們可以開(kāi)始學(xué)習(xí)注解屬性的提取了,這才是使用注解的關(guān)鍵,獲取屬性的值才是使用注解的目的。

如果獲取注解屬性,當(dāng)然是反射啦,主要有三個(gè)基本的方法

/**是否存在對(duì)應(yīng) Annotation 對(duì)象*/publicboolean isAnnotationPresent(ClassannotationClass){returnGenericDeclaration.super.isAnnotationPresent(annotationClass);? ? }/**獲取 Annotation 對(duì)象*/public A getAnnotation(ClassannotationClass){? ? ? ? Objects.requireNonNull(annotationClass);return(A) annotationData().annotations.get(annotationClass);? ? }/**獲取所有 Annotation 對(duì)象數(shù)組*/publicAnnotation[] getAnnotations() {returnAnnotationParser.toArray(annotationData().annotations);? ? }? ? 復(fù)制代碼

下面結(jié)合前面的例子,我們來(lái)獲取一下注解屬性,在獲取之前我們自定義的注解必須使用元注解@Retention(RetentionPolicy.RUNTIME)

publicclasstest {publicstaticvoidmain(String[] args)throwsNoSuchMethodException {/**

? ? ? ? * 獲取類(lèi)注解屬性

? ? ? ? */Class fatherClass = Father.class;booleanannotationPresent = fatherClass.isAnnotationPresent(MyTestAnnotation.class);if(annotationPresent){? ? ? ? ? ? MyTestAnnotation annotation = fatherClass.getAnnotation(MyTestAnnotation.class);? ? ? ? ? ? System.out.println(annotation.name());? ? ? ? ? ? System.out.println(annotation.age());? ? ? ? }/**

? ? ? ? * 獲取方法注解屬性

? ? ? ? */try{? ? ? ? ? ? Field age = fatherClass.getDeclaredField("age");booleanannotationPresent1 = age.isAnnotationPresent(Age.class);if(annotationPresent1){? ? ? ? ? ? ? ? Age annotation = age.getAnnotation(Age.class);? ? ? ? ? ? ? ? System.out.println(annotation.value());? ? ? ? ? ? }? ? ? ? ? ? Method play = PlayGame.class.getDeclaredMethod("play");if(play!=null){? ? ? ? ? ? ? ? People annotation2 = play.getAnnotation(People.class);? ? ? ? ? ? ? ? Game[] value = annotation2.value();for(Game game : value) {? ? ? ? ? ? ? ? ? ? System.out.println(game.value());? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }catch(NoSuchFieldException e) {? ? ? ? ? ? e.printStackTrace();? ? ? ? }? ? }}復(fù)制代碼

運(yùn)行結(jié)果:

JDK 提供的注解

注解作用注意事項(xiàng)

@Override它是用來(lái)描述當(dāng)前方法是一個(gè)重寫(xiě)的方法,在編譯階段對(duì)方法進(jìn)行檢查jdk1.5中它只能描述繼承中的重寫(xiě),jdk1.6中它可以描述接口實(shí)現(xiàn)的重寫(xiě),也能描述類(lèi)的繼承的重寫(xiě)

@Deprecated它是用于描述當(dāng)前方法是一個(gè)過(guò)時(shí)的方法無(wú)

@SuppressWarnings對(duì)程序中的警告去除。無(wú)

注解作用與應(yīng)用

現(xiàn)在我們?cè)俅位仡^看看開(kāi)頭官方文檔的那句描述

Java 注解用于為 Java 代碼提供元數(shù)據(jù)。作為元數(shù)據(jù),注解不直接影響你的代碼執(zhí)行,但也有一些類(lèi)型的注解實(shí)際上可以用于這一目的。

經(jīng)過(guò)我們前面的了解,注解其實(shí)是個(gè)很方便的東西,它存活的時(shí)間,作用的區(qū)域都可以由你方便設(shè)置,只是你用注解來(lái)干嘛的問(wèn)題

使用注解進(jìn)行參數(shù)配置

下面我們看一個(gè)銀行轉(zhuǎn)賬的例子,假設(shè)銀行有個(gè)轉(zhuǎn)賬業(yè)務(wù),轉(zhuǎn)賬的限額可能會(huì)根據(jù)匯率的變化而變化,我們可以利用注解靈活配置轉(zhuǎn)賬的限額,而不用每次都去修改我們的業(yè)務(wù)代碼。

/**定義限額注解*/@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public@interfaceBankTransferMoney {doublemaxMoney()default10000;}/**轉(zhuǎn)賬處理業(yè)務(wù)類(lèi)*/publicclassBankService{/**? ? * @param money 轉(zhuǎn)賬金額? ? */@BankTransferMoney(maxMoney =15000)? ? publicstaticvoidTransferMoney(doublemoney){? ? ? ? System.out.println(processAnnotationMoney(money));? ? }? ? privatestaticStringprocessAnnotationMoney(doublemoney) {try{? ? ? ? ? ? Method transferMoney = BankService.class.getDeclaredMethod("TransferMoney",double.class);? ? ? ? ? ? boolean annotationPresent = transferMoney.isAnnotationPresent(BankTransferMoney.class);if(annotationPresent){? ? ? ? ? ? ? ? BankTransferMoney annotation = transferMoney.getAnnotation(BankTransferMoney.class);doublel = annotation.maxMoney();if(money>l){return"轉(zhuǎn)賬金額大于限額,轉(zhuǎn)賬失敗";? ? ? ? ? ? ? ? }else{return"轉(zhuǎn)賬金額為:"+money+",轉(zhuǎn)賬成功";? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }catch( NoSuchMethodException e) {? ? ? ? ? ? e.printStackTrace();? ? ? ? }return"轉(zhuǎn)賬處理失敗";? ? }? ? publicstaticvoidmain(String[] args){? ? ? ? TransferMoney(10000);? ? }}復(fù)制代碼

運(yùn)行結(jié)果:

通過(guò)上面的例子,只要匯率變化,我們就改變注解的配置值就可以直接改變當(dāng)前最大限額。

第三方框架的應(yīng)用

作為一個(gè)Android 開(kāi)發(fā)者,平常我們所使用的第三方框架ButterKnife,Retrofit2,Dagger2等都有注解的應(yīng)用,如果我們要了解這些框架的原理,則注解的基礎(chǔ)知識(shí)則是必不可少的。

注解的作用

提供信息給編譯器: 編譯器可以利用注解來(lái)檢測(cè)出錯(cuò)誤或者警告信息,打印出日志。

編譯階段時(shí)的處理: 軟件工具可以用來(lái)利用注解信息來(lái)自動(dòng)生成代碼、文檔或者做其它相應(yīng)的自動(dòng)處理。

運(yùn)行時(shí)處理: 某些注解可以在程序運(yùn)行的時(shí)候接受代碼的提取,自動(dòng)做相應(yīng)的操作。

正如官方文檔的那句話所說(shuō),注解能夠提供元數(shù)據(jù),轉(zhuǎn)賬例子中處理獲取注解值的過(guò)程是我們開(kāi)發(fā)者直接寫(xiě)的注解提取邏輯,?處理提取和處理 Annotation 的代碼統(tǒng)稱(chēng)為 APT(Annotation Processing Tool)?。上面轉(zhuǎn)賬例子中的processAnnotationMoney方法就可以理解為APT工具類(lèi)。

最近整理了一套適合2019年學(xué)習(xí)的Java\大數(shù)據(jù)資料,從基礎(chǔ)的Java、大數(shù)據(jù)面向?qū)ο蟮竭M(jìn)階的框架知識(shí)都有整理哦,可以來(lái)我的主頁(yè)免費(fèi)領(lǐng)取哦。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,538評(píng)論 3 417
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,423評(píng)論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,991評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,761評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,207評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,419評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,959評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,782評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,222評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,653評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,901評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,678評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,978評(píng)論 2 374

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

  • 一 注解的定義 注解(Annotation),也叫元數(shù)據(jù)。一種代碼級(jí)別的說(shuō)明。它是JDK1.5及以后版本引入的一個(gè)...
    _那個(gè)人閱讀 3,365評(píng)論 0 3
  • 什么是注解(Annotation):Annotation(注解)就是Java提供了一種元程序中的元素關(guān)聯(lián)任何信息和...
    九尾喵的薛定諤閱讀 3,204評(píng)論 0 2
  • 從JDK5開(kāi)始,Java增加了Annotation(注解),Annotation是代碼里的特殊標(biāo)記,這些標(biāo)記可以在...
    CarlosLynn閱讀 569評(píng)論 0 2
  • java自定義注解 Java注解是附加在代碼中的一些元信息,用于一些工具在編譯、運(yùn)行時(shí)進(jìn)行解析和使用,起到說(shuō)明、配...
    尼爾君閱讀 522評(píng)論 0 0
  • 親子日記第七篇 今天周六兒子不用上學(xué),但是昨天晚上一個(gè)勁的叮囑我,今天早上一定要早...
    銘媽媽閱讀 281評(píng)論 0 3