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

java 注解的基礎詳細介紹

 更新時間:2017年09月06日 14:41:23   投稿:lqh  
這篇文章主要介紹了java 注解的基礎詳細介紹的相關資料,希望通過本文大家能掌握注解的使用方法,需要的朋友可以參考下

java 注解的基礎詳細介紹

前言

注解是Java引入的一項非常受歡迎的補充,它提供了一種結構化的,并且具有類型檢查能力的新途徑,從而使得程序員能夠為代碼加入元數(shù)據(jù),而不會導致代碼雜亂且難以閱讀。使用注解能夠幫助我們避免編寫累贅的部署描述文件,以及其他生成的文件。

注解的語法比較簡單,除了@符號的使用之外,它基本與java固有的語法一致。但由于java源碼中提供的內置注解很少,所以大部分同學對注解都不是很了解,雖然我們都接觸過,比如java內置的幾種注解:

 @Override,表示當前的方法定義將覆蓋超類中的方法。
  @Deprecated,表示當前方法即將廢棄,不推薦使用。
  @SuppressWarnings,表示忽略編譯器的警告信息。

但這并不能讓我們體會到注解的強大和便利,其實Java還另外提供了四種注解,專門負責新注解的創(chuàng)建。今天我們就來學習下怎么創(chuàng)建和使用注解。

注解類的定義

首先看看一個注解類的定義:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {
  boolean primaryKey() default false;
  boolean allowNull() default true;
  boolean unique() default false;
}

除了@符號以外,注解類的定義很像一個空的接口。定義注解時,會需要一些元注解,如@Target和@Retention,java提供了四種元注解,定義如下:

@Target:表示該注解可以用于什么地方。

取值(ElementType)包括:
CONSTRUCTOR:用于描述構造器
FIELD:用于描述域
LOCAL_VARIABLE:用于描述局部變量
METHOD:用于描述方法
PACKAGE:用于描述包
PARAMETER:用于描述參數(shù)
TYPE:用于描述類、接口(包括注解類型) 或enum聲明

@Retention:表示需要在什么級別保存該注解信息。

取值(RetentionPolicy)包括:
SOURCE:在源文件中有效(即源文件保留)
CLASS:在class文件中有效(即class保留)
RUNTIME:在運行時有效(即運行時保留),因此可以通過反射機制讀取注解的信息。

@Documented:表示將此注解包含在javadoc中。

@Inherited:表示允許子類繼承父類中的注解。

可以看出 定義注解格式為:
  public @interface 注解名 {定義體}

注解類中定義的元素稱為注解元素,注解元素可用的類型如下:

 所有基本數(shù)據(jù)類型(int,float,boolean,byte,double,char,long,short)
 String類型
 Class類型
 enum類型
 Annotation類型
 以上所有類型的數(shù)組

如果你使用了其它類型,那編譯器就會報錯。注意,也不允許使用任何包裝類型,但由于自動打包的存在,這算不上什么限制。注解也可以作為元素的類型,比如我們再定義一個注解類:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLString {
  int value() default 0;
  String name() default "";
  Constraints constraints() default @Constraints;
  //@Constraints后沒有括號表明使用默認值,可以加括號,在里面定義初始值,比如@Constraints(unique=true)
}

可以看出,所有的注解元素都有一個默認值。編譯器對元素的默認值有些過分挑剔,首先,元素必須具有默認值;其次不能以null作為默認值。所以我們只能自己定義一些特殊的值,例如空字符串或負數(shù),來表示某個元素不存在。

注解類的使用

注解類定義好了,怎么使用呢?

為了體現(xiàn)注解的便利和強大,在這里我們寫一個demo,使用注解來自動生成一個建數(shù)據(jù)庫表的SQL命令。

另外我們再提供兩個注解類:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
  public String name() default "";
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {
  String name() default "";
  Constraints constraints() default @Constraints;
}

好,現(xiàn)在我們一共有4個注解類。

@DBTable 代表數(shù)據(jù)庫表,注解元素name表示表名;
@Constraints 代表對數(shù)據(jù)表每一列的條件補充,有primaryKey是不是主鍵,默認false,allowNull是否允許為空,默認true,unique數(shù)據(jù)是否唯一,默認false;
@SQLString 代表表中的String列,注解元素value表示列長度,name表示列名,constraints表示對列的一些約束條件;
@SQLInteger 代表表中的int列,name表示列名,constraints表示對列的一些約束條件;

下面我們定義一個簡單的Bean類,在其中應用以上4個注解類:

@DBTable(name = "MEMBER")
public class Member {
  @SQLString(30) String firstName;
  @SQLString(50) String lastName;
  @SQLInteger int age;
  @SQLString(value = 30, constraints = @Constraints(primaryKey = true)) String handle;
  public String getFirstName() {
    return firstName;
  }
  public String getLastName() {
    return lastName;
  }
  public int getAge() {
    return age;
  }
  public String getHandle() {
    return handle;
  }
  public String toString() {
    return handle;
  }
}

注解的元素在使用時表現(xiàn)為名-值對的形式,并需要置于 @注解類名 聲明之后的括號內。如果沒有使用括號,代表全部使用默認值。

1、類的注解@DBTable給定了值MEMBER,它將會用來作為表的名字;

2、Bean的屬性firstName和lastName,都被注解為@SQLString類型,這些注解有兩個有趣的地方:第一,他們都使用了嵌入的@Constraints注解的默認值;第二,它們都使用了快捷方式。何謂快捷方式?如果程序員的注解中定義了名為value的元素,并且在應用該注解的時候,如果該元素是唯一需要賦值的一個元素,那么此時無需使用名-值對的這種語法,而只需在括號內給出value元素所需的值即可。這可以應用于任何合法類型的元素。當然了,這也限制了程序員必須將此元素命名為value。
Bean屬性age全部使用默認值,handle為主鍵。

3、Bean屬性age全部使用默認值,handle為主鍵。

實現(xiàn)注解處理器

注解類使用上了,我們還需要一個注解處理器來解析我們定義的Bean,這樣才能將注解轉換成我們需要的操作。

以下定義解析Bean的注解處理器,我們的目的是要輸出一條SQL語句。主要用到了反射技術。

public class TableCreator {
  public static void main(String[] args) throws Exception{
//傳入我們定義好的Bean類名,帶上包名    
Class<?> cl = Class.forName("annotation.Member");
//檢查我們傳入的類是否帶有@DBTable注解
    DBTable dbTable = cl.getAnnotation(DBTable.class);
    List<String> columnDefs = new ArrayList<String>();
//得到類中的所有定義的屬性
    for(Field filed : cl.getDeclaredFields()){
      String columnName = null;
//得到屬性的注解,對一個目標可以使用多個注解
      Annotation[] anns = filed.getAnnotations();
      if(anns.length < 1){
        continue;
      }
//SQLString注解走著
      if(anns[0] instanceof SQLString){
        SQLString sString = (SQLString)anns[0];
//name()使用的是默認值,所以這里取屬性名
        if(sString.name().length() < 1){
          columnName = filed.getName().toUpperCase();
        }else{
          columnName = sString.name();
        }
//構建SQL語句
        columnDefs.add(columnName + " VARCHAR(" + sString.value() + ")" + getConstraints(sString.constraints()));
      }
//SQLInteger注解走著
      if(anns[0] instanceof SQLInteger){
        SQLInteger sInt = (SQLInteger)anns[0];
        if(sInt.name().length() < 1){
          columnName = filed.getName().toUpperCase();
        }else{
          columnName = sInt.name();
        }
        columnDefs.add(columnName + " INT" + getConstraints(sInt.constraints()));
      }
    }
    StringBuilder creator = new StringBuilder("CREATE TABLE " + dbTable.name() + "( ");
    for(String c : columnDefs){
      creator.append("\n" + c + ",");
    }
    creator.deleteCharAt(creator.length()-1);
    creator.append(")");
    System.out.println(creator.toString());
  }

  private static String getConstraints(Constraints con) {
    String constraints = "";
    if(!con.allowNull()){
      constraints += " NOT NULL";
    }
    if(con.primaryKey()){
      constraints += " PRIMARY KEY";
    }
    if(con.unique()){
      constraints += " UNIQUE";
    }
    return constraints;
  }
}

最后的輸出:

CREATE TABLE MEMBER( 
FIRSTNAME VARCHAR(30), 
LASTNAME VARCHAR(50), 
AGE INT, 
HANDLE VARCHAR(30) PRIMARY KEY)

總結

最后,通過這篇文章,我們要學到一下幾點:

1、了解Java 4種元注解的說明與使用;
2、會自定義注解類;
3、了解注解元素的定義和規(guī)則;
4、會使用注解類;
5、能寫一個簡單的注解處理器解析注解。

如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關文章

  • SpringBoot Application注解原理及代碼詳解

    SpringBoot Application注解原理及代碼詳解

    這篇文章主要介紹了SpringBoot Application注解原理及代碼詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-06-06
  • java實現(xiàn)Dijkstra最短路徑算法

    java實現(xiàn)Dijkstra最短路徑算法

    這篇文章主要為大家詳細介紹了java實現(xiàn)Dijkstra最短路徑算法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • SpringBoot使用thymeleaf實現(xiàn)前端表格

    SpringBoot使用thymeleaf實現(xiàn)前端表格

    雖然現(xiàn)在流行前后端分離,但是后端模版在一些關鍵地方還是非常有用的,例如郵件模版、代碼模版等。當然也不排除一些古老的項目后端依然使用動態(tài)模版。Thymeleaf 簡潔漂亮、容易理解,并且完美支持 HTML5,可以直接打開靜態(tài)頁面,同時不新增標簽,只需增強屬性
    2022-10-10
  • Java中comparator接口和Comparable接口的比較解析

    Java中comparator接口和Comparable接口的比較解析

    這篇文章主要介紹了Java中comparator接口和Comparable接口的比較解析,Java提供了一個用于比較的接口Comparator和Comparable接口,提供了一個比較的方法,所有實現(xiàn)該接口的類,都動態(tài)的實現(xiàn)了該比較方法,需要的朋友可以參考下
    2023-08-08
  • 淺析java修飾符訪問權限(動力節(jié)點Java學院整理)

    淺析java修飾符訪問權限(動力節(jié)點Java學院整理)

    Java有四種訪問權限,其中三種有訪問權限修飾符,分別為private,public和protected,還有一種不帶任何修飾符,下面通過本文給大家簡單介紹下java修飾符訪問權限相關知識,感興趣的朋友一起學習吧
    2017-04-04
  • 淺析Java中String與StringBuffer拼接的區(qū)別

    淺析Java中String與StringBuffer拼接的區(qū)別

    String拼接會創(chuàng)建一個新的String對象,存儲拼接后的字符串,StringBuffer拼接是直接在本身拼接,會即時刷新。下面通過本文給大家介紹Java中String與StringBuffer拼接的區(qū)別,感興趣的朋友一起看看吧
    2017-06-06
  • java?poi之XWPFDocument如何讀取word內容并創(chuàng)建新的word

    java?poi之XWPFDocument如何讀取word內容并創(chuàng)建新的word

    這篇文章主要介紹了java?poi之XWPFDocument如何讀取word內容并創(chuàng)建新的word問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Java 高并發(fā)九:鎖的優(yōu)化和注意事項詳解

    Java 高并發(fā)九:鎖的優(yōu)化和注意事項詳解

    本文主要介紹Java高并發(fā)鎖的優(yōu)化和注意事項,這里整理了詳細的資料,并講解了 1. 鎖優(yōu)化的思路和方法 2. 虛擬機內的鎖優(yōu)化 3. 一個錯誤使用鎖的案例 4. ThreadLocal及其源碼分析等知識,有需要的小伙伴可以參考下
    2016-09-09
  • Java 實現(xiàn)簡單Socket 通信的示例

    Java 實現(xiàn)簡單Socket 通信的示例

    這篇文章主要介紹了Java 實現(xiàn)簡單Socket 通信的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下
    2021-03-03
  • JavaWeb后臺購物車類實現(xiàn)代碼詳解

    JavaWeb后臺購物車類實現(xiàn)代碼詳解

    這篇文章主要介紹了JavaWeb后臺購物車類實現(xiàn)代碼詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-07-07

最新評論

新化县| 昂仁县| 灵丘县| 辉南县| 贵溪市| 大理市| 奉贤区| 鄂温| 湘西| 张家川| 新巴尔虎右旗| 怀集县| 丁青县| 连平县| 新干县| 晴隆县| 衡阳县| 开远市| 昭苏县| 长春市| 东阳市| 禹城市| 思茅市| 普定县| 洛宁县| 林州市| 道孚县| 老河口市| 甘孜县| 滨海县| 江华| 濮阳县| 屏边| 宜君县| 雷州市| 肥城市| 山东省| 丰原市| 丰顺县| 蓬溪县| 琼结县|