Java ”框架 = 註解 + 反射 + 設計模式“ 之 註解詳解

来源:https://www.cnblogs.com/TheMagicalRainbowSea/archive/2023/02/22/17145556.html
-Advertisement-
Play Games

Java ”框架 = 註解 + 反射 + 設計模式“ 之 註解詳解 每博一文案 剎那間我真想令時光停住,好讓我回顧自己,回顧失去的年華,緬懷哪個穿一身短小的連衣裙 和瘦窄的短衫的小女孩。讓我追悔少年時代,我心靈的愚鈍無知,它輕易地錯過了我一生中本來 可以獲得歡樂和幸福。 —————— 《平凡的世界》 ...


Java ”框架 = 註解 + 反射 + 設計模式“ 之 註解詳解

在這裡插入圖片描述

每博一文案

剎那間我真想令時光停住,好讓我回顧自己,回顧失去的年華,緬懷哪個穿一身短小的連衣裙
和瘦窄的短衫的小女孩。讓我追悔少年時代,我心靈的愚鈍無知,它輕易地錯過了我一生中本來
可以獲得歡樂和幸福。
                             —————— 《平凡的世界》
                             
真的,如果痛苦不能改變生存,那還不如平靜地將自己毀滅,毀滅,一切都毀滅了,
只有生命還在苟延殘喘,這樣的生命還有有什麼存在的價值。
                            —————— 《平凡的世界》
                     

@

目錄

1. 註解的概念

註解,一種元數據形式提供了一個不屬於程式本身的程式的數據。註解對他們註解的代碼的操作沒有直接的影響。

註解有很多用途,其中:

  • 編譯器的信息 - 編譯器可以使用註解來檢測錯誤或抑制警告。
  • 編譯和部署時處理 - 軟體工具可以處理註解信息以生成代碼,XML 文件等。
  • 運行時處理 - 一些註解可以在運行時檢查

JDK5.0 開始,Java增加了對元數據(MetaData) 的支持,也就是 Annotation 註解。

  • 註解: 其實就是代碼里的 特殊標記 ,這些標記可以在編譯,類載入,運行時被讀取,並執行相應的處理。通過使用 註解,

程式員可以在不改變原有的邏輯的情況下,在源文件種嵌入一些補充的信息。代碼分析工具,開發工具和部署工具可以通過這些補充信息進行驗證或進行部署。

  • 註解: 可以像修飾符一樣被使用,可以用於 修飾:包,類,構造器,方法,成員變數,參數,局部變數的聲明 。這些信息被保存在 註解 Annotaion 的“ name = value” 鍵值對中。

  • JavaSE中,註解的使用目的比較簡單,例如標記過時的功能,忽略警告等。在JavaEE/Android中註解占據了更重要的角色,例如

    用來配置應用程式的任何切麵,代替JavaEE舊版中所遺留的繁冗 代碼和XML配置等。

  • 未來的開發模式都是基於註解的,JPA 是基於註解的,Spring2.5 以上都是基於註解的,Hibernate3.x 以後也是基於註解的,

現在Struts2 有一部分也是基於註解的了。註解是一種趨勢,一定程度上可以說:框架 = 註解 + 反射 + 設計模式

2. 註解的作用

JVM 的角度看,註解本身對代碼邏輯沒有任何影響,如何使用註解完全由工具決定。

Java的註解可以分為三類:

  • 第一類:是由編譯器使用的註解:換句話說就是給編譯器看的,不是給 JVM 看的。例如:
    • @Override : 讓編譯器檢查該方法是否正確的實現了 重寫操作。
    • @Deprecated : 表示所修飾的元素(類,方法等)已過時了,不建議使用它了。
    • @SuppressWarnings: 告訴編譯器忽略此處代碼產生的警告。
  • 第二類: 是由工具處理 .class 文件使用的註解,比如有些工具會在載入 class 的時候,對 class 做動態修改,實現一些特殊的功能。這類註解會被編譯進入到 .class 文件,但載入結束後並不會存在於記憶體中。這類註解只被一些底層使用,一般我們不必自己處理。
  • 第三類: 是在程式運行期間能夠讀取的註解,它們在載入後一直存在於 JVM 中,這也是最常用的註解。例如:一個配置了@PostConstruct 的方法會在調用構造方法後自動被調用,(這是Java代碼讀取該註解實現的功能,JVM 並不會識別該註解)。

3. 文檔註釋中的註解

在這裡插入圖片描述

在這裡插入圖片描述

  • @author 標明開發該類模塊的作者,多個作者之間使用,分割。
  • @version 標明該類的模塊的版本。
  • @see 參考轉向,也就是相關類的主題。
  • @since 從哪個版本開始增加的。
  • @param 對方法中某參數的說明,如果沒有參數就不能寫。
  • @return 對方法返回值的說明,如果方法的返回值類型是 void 就不能寫
  • @exception 對方法可能拋出的異常進行說明,如果方法沒有用 throws 顯拋出的異常就不能寫 其中:
    • @param @ return 和 @ exeption 這三個標記都是只用於方法的。
    • @param 的格式要求:@param 形參名 形參類型 形參說明
    • @return 的格式要求:@return 返回值類型 返回值說明
    • @exception 的格式要求:@exception 異常類型 異常說明
    • @ param 和 @exception 可以併列多個。

4. 自定義註解

Annotaion註解 其實也是一種引用數據類型,編譯之後也是生成 xxx.class 位元組碼文件的。

  • 定義新的 Annotation 註解 類型使用 @interface 關鍵字

  • 自定義註解自動實現了 java.lang.annotation.Annotation介面

在這裡插入圖片描述

在這裡插入圖片描述

自定義註解的格式如下:

public @interface MyAnnotation {
    
}

// 
[修飾列表] @interface 註解名/(註解類名) {
    
}

使用 IDEA 創建一個 註解類型: 滑鼠右鍵 ——> new 一個選擇 :

在這裡插入圖片描述

如下查看該 我們該自定義的註解 MyAnnotation 的 UML 圖:可以清楚的看到該 註解類型是自動繼承了該 java.lang.annotation.Annotation 介面的

在這裡插入圖片描述

但是事實上卻是自動實現了 java.lang.annotation.Annotation 介面。

在這裡插入圖片描述

Java 8之前,註解只能是在聲明的地方所使用,Java8 開始,註解可以應用 在任何地方 。這裡的任何地方包括:包,類,構造器,方法,成員變數,參數,局部變數的聲明 。這些信息被保存在 註解 Annotaion 的“ name = value” 鍵值對中。

舉例如下: 並沒有出現任何的報錯的情況。

在這裡插入圖片描述

4.1 註解中的屬性

在註解中可以定義屬性。

Java中的註解中的屬性:看著像方法,但實際在註解當中是屬性 name

格式如下:

String value();
// 數據類型 屬性名();  // 看似是方法,其實在註解中是屬性

註解中的屬性可以是任何類型:byte, short, int, long, float, double, boolean, char, String, long, Class, 枚舉類型。再或者是自定義類型。

舉例:

public @interface MyAnnotation {
    
    String value();

}

註意: 如果該註解中定義了屬性,則聲明使用該註解時 必須 為其註解中的屬性值賦上值,不然,是會報錯的。

如下,我們為該 @MyAnnotation 註解定義了屬性,使用時卻沒有賦值,報如下編譯錯誤。

在這裡插入圖片描述

為註解中的屬性賦值的格式如下:

@MyAnnotaion(value="Tom") // 註意:在該註解中定義的是什麼類型的值,就賦值對應的值,不然會報錯的
// @註解名(註解中的屬性名=對應賦值的屬性值)

舉例:

在這裡插入圖片描述

如果該註解中只有一個屬性值,並且該註解的屬性名為 value ,則在賦值時,可以省略其 為value的屬性名,直接寫值

註意一定要滿足兩個條件:1. 該註解中只有一個屬性值,2.該屬性名為 value

舉例:

在這裡插入圖片描述


為註解中的多個屬性賦值格式如下: 多個屬性值,使用逗號分隔開來,就可以了。

 @MyAnnotation(value = "Tom",value2 = "123")
// @註解名(註解中的屬性名=值,註解中的屬性名=值) :多個屬性值使用逗號分隔開。

註意: 當註解中存在多個屬性值時,其中所有該註解中的屬性值都必須賦值,不然編譯報錯,如下:

在這裡插入圖片描述

必須將註解中的所有屬性值都賦值上值才行:如下:如果註解中存在兩個或兩個以上的屬性,就算其中存在一個屬性名為 value ,其賦值時,該value 屬性名是不可以省略的。必須寫明所有的屬性名的進行賦值。[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳
在這裡插入圖片描述

註解中的屬性可以設置預設值,使用關鍵字``格式如下:

String value() default "Tom";
// 數據類型 屬性名() default  預設值;  註意需要和定義的類型保證一致。

舉例:

public @interface MyAnnotation {
    String value() default "Tom";

}

註解中屬性設置了,預設值的是可以選擇不進行賦值操作,使用定義的預設值。

舉例如下:

在這裡插入圖片描述

4.2 註解中屬性為:數組的賦值

註解中的屬性值是可以定義為數組屬性的格式如下:

String[] arr(); // 定義數組為屬性值
數據類型[] 屬性名(); 

舉例:

public @interface MyAnnotation {

    String value();

    String[] arr();

}

註解中以數組為屬性的賦值格式如下:

@MyAnnotation(value = "Tom",arr = {"hello","world"})
@註解名(屬性名=值,屬性名={值,值})

舉例:

在這裡插入圖片描述

當數組屬性所賦值的參數只有一個時,可以省略{} 花括弧。如下

在這裡插入圖片描述

5. JDK 內置的三個基本註解

下麵我們來認識一下,JDK 中三個常見的基本註解。

5.1 @Override: 限定重寫父類方法, 該註解只能用於方法

在這裡插入圖片描述

@Override : 的作用就是在編譯期間:讓編譯器檢查該方法是否正確的實現了 重寫 操作。其中的重寫的方法名是否存在錯誤,方法的返回值類型是否是父類中/介面中的一致。不一致編譯報錯,提示我們改正。

@OVerride 註解的源碼,可以看到該註解是沒有定義屬性的。

package java.lang;

import java.lang.annotation.*;

/**
 * Indicates that a method declaration is intended to override a
 * method declaration in a supertype. If a method is annotated with
 * this annotation type compilers are required to generate an error
 * message unless at least one of the following conditions hold:
 *
 * <ul><li>
 * The method does override or implement a method declared in a
 * supertype.
 * </li><li>
 * The method has a signature that is override-equivalent to that of
 * any public method declared in {@linkplain Object}.
 * </li></ul>
 *
 * @author  Peter von der Ah&eacute;
 * @author  Joshua Bloch
 * @jls 9.6.1.4 @Override
 * @since 1.5
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

註意 : 該註解只能使用在方法上(因為該註解的源碼中被@Target(ElementType.METHOD)元註解修飾了),在其他位置上是會編譯報錯的。如下:

在這裡插入圖片描述


@OVerride 註解的使用: 較少了我們編程程式時,上的簡單符號上以及一些基本的語法錯誤。

在這裡插入圖片描述

5.2 @Deprecated: 用於表示所修飾的元素(類, 方法等)已過時。

在這裡插入圖片描述

@Deprecated : 該註解表示:表示所修飾的元素(類,方法等)已過時了,不建議使用它了。建議替換成其他的方法。

@Depecated 源碼: 可以看到該註解是沒有定義屬性的。

package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

/**
 * A program element annotated &#64;Deprecated is one that programmers
 * are discouraged from using, typically because it is dangerous,
 * or because a better alternative exists.  Compilers warn when a
 * deprecated program element is used or overridden in non-deprecated code.
 *
 * @author  Neal Gafter
 * @since 1.5
 * @jls 9.6.3.6 @Deprecated
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

常見的,在我們的 java.util.lang 包下的 Date 中的 Date(String s) 構造器是被 @Deprecated 註解修飾了的。

在這裡插入圖片描述

在IDEA 中 如果我們調用了,被 @Deprecated 修飾的屬性,方法,構造器,會給一個直觀的將該屬性/方法以刪除線的方式顯示處理並提示你建議使用別的方式替換 。如下

在這裡插入圖片描述

我們也可以自己寫一個這樣的被@Deprecated 修飾的屬性/方法/類/構造器。舉例如下:

在這裡插入圖片描述

5.3 @SuppressWarnings: 抑制編譯器警告

在這裡插入圖片描述

@SuppressWarnings ** :指示應該在註解元素(以及包含在該註解元素中所有程式元素中的所有程式元素)中取消顯示指定的編譯器警告。換句話說:就是告訴編譯器忽略此處代碼產生的警告**。 註意是警告不是異常。

@SuppressWarnings的源碼 ,可以看到該註解定義了一個名為 value 的屬性。


package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

/**
 * Indicates that the named compiler warnings should be suppressed in the
 * annotated element (and in all program elements contained in the annotated
 * element).  Note that the set of warnings suppressed in a given element is
 * a superset of the warnings suppressed in all containing elements.  For
 * example, if you annotate a class to suppress one warning and annotate a
 * method to suppress another, both warnings will be suppressed in the method.
 *
 * <p>As a matter of style, programmers should always use this annotation
 * on the most deeply nested element where it is effective.  If you want to
 * suppress a warning in a particular method, you should annotate that
 * method rather than its class.
 *
 * @author Josh Bloch
 * @since 1.5
 * @jls 4.8 Raw Types
 * @jls 4.12.2 Variables of Reference Type
 * @jls 5.1.9 Unchecked Conversion
 * @jls 5.5.2 Checked Casts and Unchecked Casts
 * @jls 9.6.3.5 @SuppressWarnings
 */
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    /**
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is <i>not</i> an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     *
     * <p> The string {@code "unchecked"} is used to suppress
     * unchecked warnings. Compiler vendors should document the
     * additional warning names they support in conjunction with this
     * annotation type. They are encouraged to cooperate to ensure
     * that the same names work across multiple compilers.
     * @return the set of warnings to be suppressed
     */
    String[] value();
}

舉例: 這裡我們定義一個 int num = 1 / 0 語句,IDEA 該我們提示了警告了。

在這裡插入圖片描述

當我們加上了 @SuppressWarnings IDEA 就沒有這個警告了。如下:

在這裡插入圖片描述

在這裡插入圖片描述

具體的其他應用大家可以移步至:

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • VL11 4位數值比較器電路 根據題目真值表把情況全部列出來,純體力活。 `timescale 1ns/1ns module comparator_4( input [3:0] A , input [3:0] B , output wire Y2 , //A>B output wire Y1 , / ...
  • springboot springboot簡化了配置文件的配置,常用的spring、springmvc的配置文件已經在springboot中配置好了。使得開發更專註業務邏輯的實現,提高開發效率。 1.1基於xml的配置 spring配置文件 <?xml version="1.0" encoding= ...
  • /* * @Author: DEFT:[email protected] V:NOTFOUND6O6 * @Date: 2023-02-22 19:02:35 * @LastEditors: Please set LastEditors * @LastEditTime: 2023-02-22 ...
  • 2023-02-22 1、Git常用命令 (1)Git中的初始化 git init (2)查看文件狀態 git status (3)將內容提交到暫存區 git add 文件的名稱 (4)將內容提交到本地倉庫 git commit -m "這裡放置本次提交的說明" (5)複合形式——將內容提交到暫存區 ...
  • 模塊的基本使用 模塊使用步驟 創建模塊(創建模塊,創建包,創建類,定義方法) -創建兩個模塊myOne,myTwo 在模塊的src目錄下創建module-info.java的描述性文件,該文件專門定義模塊名,訪問許可權,模塊依賴等信息 -描述性文件中使用模塊導出和模塊依賴來進行配置並使用 模塊中所有未 ...
  • 迭代器:迭代的工具。迭代是更新換代,如你爺爺生了你爹,你爹生了你,迭代也可以說成是重覆,並且但每一次的重覆都是基於上一次的結果來的。如電腦中的迭代開發,就是基於軟體的上一個版本更新。以下代碼就不是迭代,它只是單純的重覆 while True: print('*'*10) 一、可迭代對象 pytho ...
  • Mybatis介紹與入門 1.官方文檔 Mybatis中文手冊:mybatis – MyBatis 3 或者 MyBatis中文網 Maven倉庫:Maven Repository: org.mybatis » mybatis » 3.5.7 (mvnrepository.com) 2.概述 2.1 ...
  • 原神是由米哈游製作發行的一款開放世界冒險游戲,號稱全球玩家5600W,可以說是非常熱門了,朋友都說好玩,哎,但我就是不玩,就是皮… 但是,今天我就要用python來打開“原神世界”的大門!探索一下游戲角色! 話不多說直接開整! 準備工作 這是本次需要使用到 的工具 nodejs pyexecjs r ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...