欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java 注解的基礎(chǔ)詳細(xì)介紹

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

java 注解的基礎(chǔ)詳細(xì)介紹

前言

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

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

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

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

注解類的定義

首先看看一個(gè)注解類的定義:

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

除了@符號(hào)以外,注解類的定義很像一個(gè)空的接口。定義注解時(shí),會(huì)需要一些元注解,如@Target和@Retention,java提供了四種元注解,定義如下:

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

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

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

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

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

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

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

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

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

如果你使用了其它類型,那編譯器就會(huì)報(bào)錯(cuò)。注意,也不允許使用任何包裝類型,但由于自動(dòng)打包的存在,這算不上什么限制。注解也可以作為元素的類型,比如我們?cè)俣x一個(gè)注解類:

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

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

注解類的使用

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

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

另外我們?cè)偬峁﹥蓚€(gè)注解類:

@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個(gè)注解類。

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

下面我們定義一個(gè)簡單的Bean類,在其中應(yīng)用以上4個(gè)注解類:

@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;
  }
}

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

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

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

3、Bean屬性age全部使用默認(rèn)值,handle為主鍵。

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

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

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

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;
//得到屬性的注解,對(duì)一個(gè)目標(biāo)可以使用多個(gè)注解
      Annotation[] anns = filed.getAnnotations();
      if(anns.length < 1){
        continue;
      }
//SQLString注解走著
      if(anns[0] instanceof SQLString){
        SQLString sString = (SQLString)anns[0];
//name()使用的是默認(rèn)值,所以這里取屬性名
        if(sString.name().length() < 1){
          columnName = filed.getName().toUpperCase();
        }else{
          columnName = sString.name();
        }
//構(gòu)建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)

總結(jié)

最后,通過這篇文章,我們要學(xué)到一下幾點(diǎn):

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

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

相關(guān)文章

  • Spring集成PageHelper的簡單用法示例

    Spring集成PageHelper的簡單用法示例

    這篇文章主要介紹了Spring集成PageHelper的簡單用法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • JAVA中的final關(guān)鍵字用法實(shí)例詳解

    JAVA中的final關(guān)鍵字用法實(shí)例詳解

    這篇文章主要介紹了JAVA中的final關(guān)鍵字用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Java中的final關(guān)鍵字用于修飾數(shù)據(jù),方法及類的具體使用技巧,需要的朋友可以參考下
    2015-12-12
  • 淺析java中String類型中“==”與“equal”的區(qū)別

    淺析java中String類型中“==”與“equal”的區(qū)別

    這篇文章主要介紹了淺析java中String類型中“==”與“equal”的區(qū)別,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 使用@Valid+BindingResult進(jìn)行controller參數(shù)校驗(yàn)方式

    使用@Valid+BindingResult進(jìn)行controller參數(shù)校驗(yàn)方式

    這篇文章主要介紹了使用@Valid+BindingResult進(jìn)行controller參數(shù)校驗(yàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Spring純Java配置集成kafka代碼實(shí)例

    Spring純Java配置集成kafka代碼實(shí)例

    這篇文章主要介紹了Spring純Java配置集成kafka代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • SpringBoot訪問請(qǐng)求404解決方法

    SpringBoot訪問請(qǐng)求404解決方法

    這篇文章主要介紹了SpringBoot訪問請(qǐng)求404解決方法,文中有詳細(xì)的解決方法供大家參考,對(duì)我們學(xué)習(xí)或工作有一定的幫助,需要的朋友跟著小編一起來學(xué)習(xí)吧
    2023-07-07
  • Spring Boot集成Ehcache緩存解決方式

    Spring Boot集成Ehcache緩存解決方式

    在本篇文章里小編給大家整理的是關(guān)于Spring Boot集成Ehcache緩存解決方式,需要的朋友們可以學(xué)習(xí)下。
    2019-12-12
  • 升級(jí)springboot3.x踩坑記錄

    升級(jí)springboot3.x踩坑記錄

    本文主要介紹了升級(jí)springboot3.x踩坑記錄,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • MyBatis-Plus如何關(guān)閉SQL日志打印詳解

    MyBatis-Plus如何關(guān)閉SQL日志打印詳解

    在使用mybatisplus進(jìn)行開發(fā)時(shí),日志是一個(gè)非常有用的工具,它可以幫助我們更好地了解和調(diào)試我們的代碼,這篇文章主要給大家介紹了關(guān)于MyBatis-Plus如何關(guān)閉SQL日志打印的相關(guān)資料,需要的朋友可以參考下
    2024-03-03
  • spring boot整合kafka過程解析

    spring boot整合kafka過程解析

    這篇文章主要介紹了spring boot整合kafka過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02

最新評(píng)論