1. 程式人生 > >教科書級講解,秒懂最詳細Java的註解

教科書級講解,秒懂最詳細Java的註解

所有知識體系文章,GitHub已收錄,歡迎Star!再次感謝,願你早日進入大廠!

GitHub地址: https://github.com/Ziphtracks/JavaLearningmanual

Java註解

一、Java註解概述

註解(Annotation),也叫元資料。一種程式碼級別的說明。它是JDK1.5及以後版本引入的一個特性,與類、介面、列舉是在同一個層次。它可以宣告在包、類、欄位、方法、區域性變數、方法引數等的前面,用來對這些元素進行說明,註釋。

二、註解的作用分類

  • 編寫文件: 通過程式碼裡標識的元資料生成文件【生成文件doc文件】
  • 程式碼分析: 通過程式碼裡標識的元資料對程式碼進行分析【使用反射】
  • 編譯檢查: 通過程式碼裡標識的元資料讓編譯器能夠實現基本的編譯檢查【Override等】

編寫文件

首先,我們要知道Java中是有三種註釋的,分別為單行註釋、多行註釋和文件註釋。而文件註釋中,也有@開頭的元註解,這就是基於文件註釋的註解。我們可以使用javadoc命令來生成doc文件,此時我們文件的內元註解也會生成對應的文件內容。這就是編寫文件的作用。

程式碼分析

我們頻繁使用之一,也是包括使用反射來通過程式碼裡標識的元資料對程式碼進行分析的,此內容我們在後續展開講解。

編譯檢查

至於在編譯期間在程式碼中標識的註解,可以用來做特定的編譯檢查,它可以在編譯期間就檢查出“你是否按規定辦事”,如果不按照註解規定辦事的話,就會在編譯期間飄紅報錯,並予以提示資訊。可以就可以為我們程式碼提供了一種規範制約,避免我們後續在程式碼中處理太多的程式碼以及功能的規範。比如,@Override註解是在我們覆蓋父類(父介面)方法時出現的,這證明我們覆蓋方法是繼承於父類(父介面)的方法,如果該方法稍加改變就會報錯;@FunctionInterface註解是在編譯期檢查是否是函式式介面的,如果不遵循它的規範,同樣也會報錯。

三、jdk的內建註解

3.1 內建註解分類

  • @Override: 標記在成員方法上,用於標識當前方法是重寫父類(父介面)方法,編譯器在對該方法進行編譯時會檢查是否符合重寫規則,如果不符合,編譯報錯。
  • @Deprecated: 用於標記當前類、成員變數、成員方法或者構造方法過時如果開發者呼叫了被標記為過時的方法,編譯器在編譯期進行警告。
  • @SuppressWarnings: 壓制警告註解,可放置在類和方法上,該註解的作用是阻止編譯器發出某些警告資訊。

3.2 @Override註解

標記在成員方法上,用於標識當前方法是重寫父類(父介面)方法,編譯器在對該方法進行編譯時會檢查是否符合重寫規則,如果不符合,編譯報錯。

這裡解釋一下@Override註解,在我們的Object基類中有一個方法是toString方法,我們通常在實體類中去重寫此方法來達到列印物件資訊的效果,這時候也會發現重寫的toString方法上方就有一個@Override註解。如下所示:

image-20200604203535421

於是,我們試圖去改變重寫後的toString方法名稱,將方法名改為toStrings。你會發現在編譯期就報錯了!如下所示:

image-20200604203645332

那麼這說明什麼呢?這就說明該方法不是我們重寫其父類(Object)的方法。這就是@Override註解的作用。

3.3 @Deprecated註解

用於標記當前類、成員變數、成員方法或者構造方法過時如果開發者呼叫了被標記為過時的方法,編譯器在編譯期進行警告。

我們解釋@Deprecated註解就需要模擬一種場景了。假設我們公司的產品,目前是V1.0版本,它為使用者提供了show1方法的功能。這時候我們為產品的show1方法的功能又進行了擴充套件,打算髮布V2.0版本。但是,我們V1.0版本的產品需要拋棄嗎?也就是說我們V1.0的產品功能還繼續讓使用者使用嗎?答案肯定是不能拋棄的,因為有一部分使用者是一直用V1.0版本的。如果拋棄了該版本會損失很多的使用者量,所以我們不能拋棄該版本。這時候,我們對功能進行了擴充套件後,釋出了V2.0版本,我們給予使用者的通知就可以了,也就是告知使用者我們在V2.0版本中為功能進行了擴充套件。可以讓使用者自行選擇版本。

但是,除了釋出告知使用者版本情況之外,我們還需要在原來版本的功能上給予提示,在上面的模擬場景中我們需要在show1方法上方加@Deprecated註解給予提示。通過這種方式也告知使用者“這是舊版本時候的功能了,我們不建議再繼續使用舊版本的功能”,這句話的意思也就正是給使用者做了提示。使用者也會這麼想“奧,這版本的這個功能不好用了,肯定有新版本,又更好用的功能。我要去官網查一下下載新版本”,還會有使用者這麼想“我明白了,又更新出更好的功能了,但是這個版本的功能我已經夠用了,不需要重新下載新版本了”。

那麼我們怎麼檢視我上述所說的在功能上給予的提示呢?這時候我需要去建立一個方法,然後去呼叫show1方法,並檢視呼叫時它是如何提示的。

圖已經貼出來了,你是否發現的新舊版本功能的異同點呢?很明顯,在方法中的提示是在呼叫的方法名上加了一道橫線把該方法劃掉了。這就體現了show1方法過時了,已經不建議使用了,我們為你提供了更好的。

回想起來,在我們的api中也會有方法是過時的,比如我們的Date日期類中的方法有很多都已經過時了。如下圖:

image-20200604210154348
image-20200604210416762

如你所見,是不是有很多方法都過時了呢?那它的方法上是加了@Deprecated註解嗎?來跟著我的腳步,我帶你們看一下。

我們已經知道的Date類中的這些方法已經是過時的了,如果我們使用該方法並執行該程式的話。執行的過程中就會提示該方法已過時的內容,但是隻是提示,並不影響你使用該方法。如下:

image-20200604221938895

OK!這也就是@Deprecated註解的作用了。

3.4 @SuppressWarnings註解

壓制警告註解,可放置在類和方法上,該註解的作用是阻止編譯器發出某些警告資訊,該註解為單值註解,只有 一個value引數,該引數為字串陣列型別,引數值常用的有如下幾個。

  • unchecked:未檢查的轉化,如集合沒有指定型別還新增元素
  • unused:未使用的變數
  • resource:有泛型未指定型別
  • path:在類路徑,原檔案路徑中有不存在的路徑
  • deprecation:使用了某些不贊成使用的類和方法
  • fallthrough:switch語句執行到底沒有break關鍵字
  • rawtypes:沒有寫泛型,比如: List list = new ArrayList();
  • all:全部型別的警告

壓制警告註解,顧名思義就是壓制警告的出現。我們都知道,在Java程式碼的編寫過程中,是有很多黃色警告出現的。但是我不知道你的導師是否教過你,程式設計師只需要處理紅色的error,不需要理會黃色的warning。如果你的導師說過此問題,那是有原因的。因為在你學習階段,我們認清處理紅色的error即可,這樣可以減輕你學習階段在腦部的記憶內容。如果你剛剛加入學習Java的佇列中,需要大腦記憶的東西就有太多了,也就是我們目前不需要額外記憶其他的東西,只記憶重點即可。至於黃色warning嘛,在你的學習過程中慢慢就會有所瞭解的,而不是死記硬背的。

那為了解釋@SuppressWarnings註解,我們還使用上一個例子,因為在那個例子中就有黃色的warning出現。

而每一個黃色的warning都會有警告資訊的。比如,這一個圖中的警告資訊,就告知你show2()方法沒有被使用,簡單來說,你建立的show2方法,但是你在程式碼中並沒有呼叫過此方法。以後你便會遇到各種各樣黃色的warning。然後, 我們就可以使用不同的註解引數來壓制不同的註解。但是在該註解的引數中,提供了一個all引數可以壓制全部型別的警告。而這個註解是需要加到類的上方,並賦予all引數,即可壓制所有警告。如下:

image-20200604213943722

我們加入註解並賦予all引數後,你會發現use方法和show2方法的警告沒有了,實際上導Date包的警告還在,因為我們Date包匯入到了該類中,但是我們並沒有建立Date物件,也就是並沒有寫入Date在程式碼中,你也會發現那一行是灰色的,也就證明了我們沒有去使用匯入這個包的任何資訊的說法,出現這種情況我們就需要把這個沒有用的導包內容刪除掉,使用Ctrl + X刪除匯入沒有用到的包即可。還有一種辦法就是在包的上方修飾壓制警告註解,但是我認為在一個沒有用的包上加壓制註解是毫無意義的,所以,我們直接刪除就好。

然後,我們還見到上圖,註解那一行出現了警告資訊提示。這一行的意思是冗餘的警告壓制。這就是說我們壓制以下的警告並沒有什麼意義而造成的冗餘,但是如果我們使用了該類並做了點什麼的話,壓制註解的冗餘警告就會消失,畢竟我們使用了該類,此時就不會早場冗餘了。

上述解釋@SuppressWarnings註解也差不多就這些了。OK,繼續向下看吧。持續為大家講解。

3.5 @Repeatable註解

@Repeatable 表明標記的註解可以多次應用於相同的宣告或型別,此註解由Java8版本引入。我們知道註解是不能重複定義的,其實該註解就是一個語法糖,它可以重複多此使用,更適用於我們的特殊場景。

首先,我們先建立一個可以重複使用的註解。

package com.mylifes1110.anno;

import java.lang.annotation.Repeatable;

@Repeatable(Hour.class)
public @interface Hours {
    double[] hours() default 0;
}

你會發現註解要求傳入的值是一個類物件,此類物件就需要傳入另外一個註解,這裡也就是另外一個註解容器的類物件。我們去建立一下。

package com.mylifes1110.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//容器
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Hour {
    Hours[] value();
}

其實,這兩個註解的套用,就是將一個普通的註解封裝了一個可重複使用的註解,來達到註解的複用性。最後,我們建立一下測試類,隨後帶你去看一下原始碼。

package com.mylifes1110.java;

import com.mylifes1110.anno.Hours;

@Hours(hours = 4)
@Hours(hours = 4.5)
@Hours(hours = 2)
public class Worker {
    public static void main(String[] args) {
        //通過Hours註解型別來獲取Worker中的值陣列物件
        Hours[] hours = Worker.class.getAnnotationsByType(Hours.class);
        //遍歷陣列
        for (Hours h : hours) {
            System.out.println(h);
        }
    }
}

測試類,是一個工人測試類,該工人使用註解記錄早中晚的工作時間。測試結果如下:

image-20200606183652359

然後我們進入到原始碼一探究竟。

image-20200606183737877

我們發現進入到原始碼後,就只看見一個返回值為類物件的抽象方法。這也就驗證了該註解只是一個可實現重複性註解的語法糖而已。

四、註解分類

4.1 註解分類

註解可以根據註解引數分為三大類:

  • 標記註解: 沒有引數的註解,僅用自身的存在與否為程式提供資訊,如@Override註解,該註解沒有引數,用於表示當前方法為重寫方法。
  • 單值註解: 只有一個引數的註解,如果該引數的名字為value,那麼可以省略引數名,如 @SuppressWarnings(value = "all"),可以簡寫為@SuppressWarnings("all")。
  • 完整註解: 有多個引數的註解。

4.2 標記註解

說到@Override註解是一個標記註解,那我們進入到該註解的原始碼檢視一下。從上往下看該註解原始碼,發現它繼承了匯入了java.lang.annotation.*,也就是有使用到該包的內容。然後下面就又是兩個看不懂的註解,其實發現註解的定義格式是public修飾的@Interface,最終看到該註解中方法體並沒有任何引數,也就是隻起到標記作用。

4.3 單值註解

在上面我們用到的@SuppressWarnings註解就是一個單值註解。那我們進入到它的原始碼看一下是怎麼個情況。其實,和標記註解比較,它就多一個value引數而已,而這就是單值註解的必要條件,即只有一個引數。並且這一個引數為value時,我們可以省略value。

4.4 完整註解

上述兩個型別註解講解完,至於完整註解嘛,這下就能更明白了。其中的方法體就是有多個引數而已。

五、自定義註解

5.1 自定義註解格式

格式: public @Interface 註解名 {屬性列表/無屬性}

注意: 如果註解體中無任何屬性,其本質就是標記註解。但是與其標註註解還少了上邊修飾的元註解。

如下,這就是一個註解。但是它與jdk自定義註解有點區別,jdk自定義註解的上方還有註解來修飾該註解,而那註解就叫做元註解。元註解我會在後面詳細的說到。

image-20200606104149069

這裡我們的確不知道@Interface是什麼,那我們就把自定義的這個註解反編譯一下,看一下反編譯資訊。反編譯操作如下:

image-20200606104818131

反編譯後的反編譯內容如下:

public interface com.mylifes1110.anno.MyAnno extends java.lang.annotation.Annotation {
}

首先,看過反編譯內容後,我們可以直觀的得知他是一個介面,因為它的public修飾符後面的關鍵字是interface。

其次,我們發現MyAnno這個介面是繼承了java.lang.annotation包下的Annotation介面。

所以,我們可以得知註解的本質就是一個介面,該介面預設繼承了Annotation介面。

既然,是繼承的Annotation介面,那我們就去進入到這個介面中,看它定義了什麼。以下是我抽取出來的介面內容。我們發現它看似很常見,其實它們不是很常用,作為了解即可。

public interface Annotation {
    boolean equals(Object obj);
    int hashCode();
    String toString();
    Class<? extends Annotation> annotationType();
}

最後,我們的註解中也是可以寫有屬性的,它的屬性不同於普通的屬性,它的屬性是抽象方法。既然註解也是一個介面,那麼我們可以說介面體中可以定義什麼,它同樣也可以定義,而它的修飾符與介面一樣,也是預設被public abstract修飾。

而註解體中的屬性也是有要求的。其屬性要求如下:

  • 屬性的返回值型別必須是以下幾種:
  • 基本資料型別
  • String型別
  • 列舉型別
  • 註解
  • 以上型別的陣列
  • 注意: 在這裡不能有void的無返回值型別和以上型別以外的型別
  • 定義的屬性,在使用時需要給註解中的屬性賦值
  • 如果定義屬性時,使用default關鍵字給屬性預設初始化值,則使用註解時可以不為屬性賦值,它取的是預設值。如果為它再次傳入值,那麼就發生了對原值的覆蓋。
  • 如果只有一個屬性需要賦值,並且屬性的名稱為value,則賦值時value可以省略,可以直接定義值
  • 陣列賦值時,值使用{}儲存值。如果陣列中只有一個值,則可以省略{}

5.2 自定義註解屬性的返回值

屬性返回值既然有以上幾種,那麼我就在這裡寫出這幾種演示一下是如何寫的。

首先,定義一個列舉類和另外一個註解備用。

package com.mylifes1110.enums;

public enum Lamp {
    RED, GREEN, YELLOW
}
package com.mylifes1110.anno;

public @interface MyAnno2 {
}

其次,我們來定義上述幾種型別,如下:

package com.mylifes1110.anno;

import com.mylifes1110.enums.Lamp;

public @interface MyAnno {
    //基本資料型別
    int num();

    //String型別
    String value();

    //列舉型別
    Lamp lamp();

    //註解型別
    MyAnno2 myAnno2();

    //以上型別的陣列
    String[] values();
    Lamp[] lamps();
    MyAnno2[] myAnno2s();
    int[] nums();
}

5.3 自定義註解的屬性賦值

這裡我們演示一下,首先,我們使用該註解來進行演示。

package com.mylifes1110.anno;

public @interface MyAnno {
    //基本資料型別
    int num();

    //String型別
    String value();
}

隨後建立一個測試類,在類的上方寫上註解,你會發現,註解的引數中會讓你寫這兩個引數(int、String)。

image-20200606113037920

此時,傳參是這樣來做的。格式為:名稱 = 返回值型別引數。如下:

上述所說,如果使用default關鍵字給屬性預設初始化值,就不需要為其引數賦值,如果賦值的話,就把預設初始化的值覆蓋掉了。

當然還有一個規則,如果只有一個屬性需要賦值,並且屬性的名稱為value,則賦值時value可以省略,可以直接定義值。那麼,我們的num已經有了預設值,就可以不為它傳值。我們發現,註解中定義的屬性就剩下了一個value屬性值,那麼我們就可以來演示這個規則了。

image-20200606113849685

這裡,我並沒有寫屬性名稱value,而是直接為value賦值。如果我將num的default關鍵字修飾去掉呢,那意思也就是說在使用該註解時必須為num賦值,這樣可以省略value嗎?那我們看一下。

image-20200606114216801

結果,就是我們所想的,它報錯了,必須讓我們給num賦值。其實想想這個規則也是很容易懂的,定義一個為value的值,就可以省略其value名稱。如果定義多個值,它們可以省略名稱就無法區分定義的是那個值了,關鍵是還有陣列,陣列內定義的是多個值呢,對吧。

5.4 自定義註解的多種返回值型別賦值

這裡我們演示一下,上述的多種返回值型別是如何賦值的。這裡我們定義這幾個引數來看一下,是如何為屬性賦值的。

num是一個int基本資料型別,即num = 1

value是一個String型別,即value = "str"

lamp是一個列舉型別,即lamp = Lamp.RED

myAnno2是一個註解型別,即myAnno2 = @MyAnno2

values是一個String型別陣列,即values = {"s1", "s2", "s3"}

values是一個String型別陣列,其陣列中只有一個值,即values = "s4"

注意: 值與值之間是,隔開的;陣列是用{}來儲存值的,如果陣列中只有一個值可以省略{};列舉型別是列舉名.列舉值

六、元註解

6.1 元註解分類

元註解就是用來描述註解的註解。一般使用元註解來限制自定義註解的使用範圍、生命週期等等。

而在jdk的中java.lang.annotation包中定義了四個元註解,如下:

元註解 描述
@Target 指定被修飾的註解的作用範圍
@Retention 指定了被修飾的註解的生命週期
@Documented 指定了被修飾的註解是可以Javadoc等工具文件化
@Inherited 指定了被修飾的註解修飾程式元素的時候是可以被子類繼承的

6.2 @Target

@Target 指定被修飾的註解的作用範圍。其作用範圍可以在原始碼中找到引數值。

相關推薦

教科書講解詳細Java註解

所有知識體系文章,GitHub已收錄,歡迎Star!再次感謝,願你早日進入大廠! GitHub地址: https://github.com/Ziphtracks/JavaLearningmanual Java註解 一、Java註解概述 註解(Annotation),也叫元資料。一種程式碼級別的說明。它是

C++模板Template的使用精簡詳解

    為了能夠完整地描述模板的建立和具體使用,以下會有完善的測試,請大家耐心看下去,基本可以看得懂,即學即用。// CPP面向物件.cpp: 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <iostream> u

關於雲原生這是詳細的技術知識

本文旨在揭示現代軟體行業的關鍵主題——雲原生應用程式。這篇文章涉及微服務、容器和無伺服器應用程式。在這裡,我們將討論這些技術的實際優點和缺點。 微服務是什麼 微服務架構作為構建現代軟體應用程式的強大方法而享有盛譽。那麼什麼是微服務?微服務可以簡單地描述

高新技術企業認定史上詳細的申請攻略!(深度好文)

相關 str 直接 方式 項目 微信 組織 名片 數據 在市場廣闊的今天,基本每個省和市地×××府都會建立產業園區或高新技術企業優化孵化帶,提供各種政策支持、稅收優惠以及財政補助。同時,高新技術企業資質對企業來說是一張閃亮的名片,相當於中國的品牌馳名商標,不僅能夠為企業帶來

JDK中多執行緒之JUC集合的JDK原始碼解讀配合大神的一起看

一、    “JUC集合”01之框架 1)  概要 之前,在"Java 集合系列目錄(Category)"中,講解了Java集合包中的各個類。接下來,將展開對JUC包中的集合進行學習。在學習之前,先溫習一下"Java集合包"。本章內容包括: Java集合包 JUC中的

JDK中集合包Collection和List的原始碼解讀配合大神的一起看

大神總結的目錄:http://www.cnblogs.com/skywang12345/p/3323085.html(轉載),僅供個人學習,如有抄襲請包容(我也忘了cry....) 一、    總體架構 1)  簡介 Java集合是java提供的工具包,包含了常用的資料

史上詳細Java內存區域講解

種類 元數據 設置meta 技術 int 大小 ron 選擇 方法 常見面試題 基本問題 介紹下 Java 內存區域(運行時數據區) Java 對象的創建過程(五步,建議能默寫出來並且要知道每一步虛擬機做了什麽) 對象的訪問定位的兩種方式(句柄和直接指針兩種方式) 拓展

史上詳細Java記憶體區域講解

常見面試題 基本問題 介紹下 Java 記憶體區域(執行時資料區) Java 物件的建立過程(五步,建議能默寫出來並且要知道每一

金九銀十史上Java 面試題整理。

dir db2 計算 2.0 dad map rec 比較 ef6 以下會重新整理所有 Java 系列面試題答案、及各大互聯網公司的面試經驗,會從以下幾個方面匯總,本文會長期更新。 Java 面試篇 史上最全 Java 面試題,帶全部答案 史上最全 69 道 Spring

樹上倍增的寫法和應用(詳細講解新手

        最近做了一些樹上的練習題,發現倍增真的是一種處理樹上問題的神奇、方便的方法。 我以前一直打樹鏈剖分打得多,但是學了倍增之後就再也不想打樹鏈剖分了(當然有些題目不得不打)。 倍增比起樹

java 泛型詳解-絕對是對泛型方法講解詳細沒有之一

對java的泛型特性的瞭解僅限於表面的淺淺一層,直到在學習設計模式時發現有不瞭解的用法,才想起詳細的記錄一下。 本文參考java 泛型詳解、Java中的泛型方法、 java泛型詳解 1. 概述 泛型在java中有很重要的地位,在面向物件程式設計及各種設計模式中有非常廣泛

try catch finally 的用法你知道多少?詳細到位的講解配合程式碼例項講解讓你輕鬆掌握和理解

廢話就不多說了,關於 try catch 相信各位已經不陌生了,但是真正意義上會用它呢,還是有欠缺的,為什麼這麼說呢?因為博主也 是在做一個專案的時候遇到了這樣的問題,去看了下 API 才想起來,於是乎就順便寫了這篇部落格分享出來,方便大家觀看和學習以 及理解,等下筆者會按

一個很詳細的RxJava講解一看就

這是轉載的第二篇RxJava的文章了,感覺比之前的那篇寫得好,更易懂且更全面。 當然學習框架不在於看幾篇文章,而在於做多少練習,然而看到還是覺得值得一轉。 前言 使用了RxJava有一段時間了,深深感受到了其“牛逼”之處。下面,就從RxJava的

ac自動機詳細講解讓你一次學會ac自動機。【轉載】

在沒學ac自動機之前,覺得ac自動機是個很神奇,很高深,很難的演算法,學完之後發現,ac自動機確實很神奇,很高深,但是卻並不難。  我說ac自動機很神奇,在於這個演算法中失配指標的妙處(好比kmp演算法中的next陣列),說它高深,是因為這個不是一般的演算法,而是建立在兩

Nodejs 入門祕籍搭一個簡單的web伺服器。(菜鳥的你也能

心血來潮,總結了一個Nodejs入門祕籍。看了你就想學NodeJs了。一、簡單介紹nodejs初學nodejs  ,直接上簡單例項。先簡單說明一下:nodejs ,nodejs相當於伺服器端的 可以輕易搭建一個伺服器端。 nodejs是用C++開發的一種運行於伺服器端的語言

史上詳細的Android Studio百度地圖(BaiDuMap)開發教程可以當作官方文件的教科書級別教程!

本文是續寫一一哥作品,(一些大神沒想過要寫出來的,而笨小白又不懂的,,稍有完善。) 原文:http://blog.csdn.net/syc000666/article/details/50756551 由於工作原因,需要用到地圖模組,之前一直是用Eclipse開發百度地圖

史上詳細JVMJava記憶體區域講解

本人免費整理了Java高階資料一共30G,需要自己領取; 傳送門:https://mp.weixin.qq.co

系列詳細Java列舉教程!!!

**所有知識體系文章,[GitHub](https://github.com/Ziphtracks/JavaLearningmanual)已收錄,歡迎Star!再次感謝,願你早日進入大廠!** **GitHub地址:** [https://github.com/Ziphtracks/JavaLearning

Plupload 上傳詳細講解Plupload 多實例上傳Plupload多個上傳按鈕--推薦使用

.html 目前 clas 路徑 arc 我們 參考 等等 選擇 今天幫朋友解決 Plupload 上傳的問題,查了很多資料,資料還是挺全的,但是有點零零散散的,故整理好,合並發出來。 本教程包括: Plupload 上傳詳細講。 Plupload 多實例

spring mvc 詳細文檔前無古人後無來者 掉渣天~

get() tom include ava spa .com ops images 類型 一、SpringMVC基礎入門,創建一個HelloWorld程序 1.首先,導入SpringMVC需要的jar包。 2.添加Web.xml配置文件中關於SpringMVC的配置

屬性 描述