很多碼農在寫代碼的時候不太愛寫注釋,結果任務一多,時間一長,需求一改,就完全不知道當初自己都干了些啥了,好在現在大多數編程語言都有注釋功能,能夠在代碼里面做一些備注,不至于時間長了忘掉,但這些注釋只是給人看的,機器并不會處理這些資訊,而是把這些注釋當作垃圾一樣無視,
反過來,如果有些編程語言因為升級更新,替換掉了某些功能特性而導致開發受阻甚至不能使用,該怎么辦呢?——這也難不倒科學家,他們想:既然碼農可以寫注釋提醒自己不忘記代碼是干什么的,那是不是也可以通過某種方法來提醒他們代碼會出問題呢?
還真被他們找到了,這就是注解!
比如,像剛才說的場景:如果某個Java類被廢棄了,怎么讓碼農們知道呢?——使用@Deprecated注解的就可以辦到,就像這樣:

如果類的方法被廢棄,也是一樣:

注解是JDK1.5中新增加的特性,它的作用說白了就是Java語言層面的「注釋」,它主要是用來向JVM(Java虛擬機)解釋說明類、物件、方法、屬性、介面、抽象類等元素的資訊,它是對資料的描述,可以說是關于資料的資料,
Java中提供了一些預定義的注解,例如@Override、@SuppressWarnings、@FunctionalInterface等,而Java開發框架的頂流Spring又在在此之上,提供了更多的注解,例如@Autowired、@Service、@RestController,
因為有了這些注解,碼農的開發效率大大提高,舉個最常見的栗子來說:
沒有使用@Autowired注解:
/** * 用戶介面控制器 * * @author 湘王 */ public class UserController { private UserService userService; // 用戶登錄介面 public void login(User user) { // 先實體化UserService的實作類UserServiceImpl userService = new UserServiceImpl(); // 繼續實體化UserServiceImpl類中需要用到的各種其他類和物件 // TODO } // 用戶登出介面 public void logout(String userid) { // 同樣的程序可能要再來一次 userService = new UserServiceImpl(); // 繼續實體化UserServiceImpl類中需要用到的各種其他類和物件 // TODO } }
使用了@Autowired注解:
/** * 用戶介面控制器 * * @author 湘王 */ public class UserController { @Autowired private UserService userService; // 用戶登錄介面 public void login(User user) { // 直接呼叫UserServiceImpl實作類的各種物件和方法 // TODO } // 用戶登出介面 public void logout(String userid) { // 直接呼叫UserServiceImpl實作類的各種物件和方法,而且不用重復實體化 // TODO } }
用了注解之后可以說是「舒服得不能再舒服了」,
Java目前提供了五種標準的注解(元注解,就是可以用來創造其他注解的注解)
@Target:表示注解可以用于哪些地方
@Retention:表示注解的適用范圍
@Documented:將注解保存在javadoc中
@Inherited:允許子類繼承父類的注解
@Repeatable:允許一個注解可被使用一次或多次
/** * 定義注解可以應用在哪里 * PACKAGE:包 * TYPE:類、介面(包括注解型別)或者enum * CONSTRUCTOR:構造器 * METHOD:方法 * FIELD:欄位(包括enum實體) * LOCAL_VARIABLE:區域變數 * PARAMETER:引數 * * 如果省去@Target注解,那么注解可以應用于所有的ElementType * * @author xiangwang */ @Target(ElementType.METHOD) /** * 定義了注解在哪里可用 * SOURCE:源代碼,將被編譯器丟棄 * CLASS:class檔案,會被JVM丟棄 * RUNTIME:運行時,一直保留 */ @Retention(RetentionPolicy.RUNTIME) // 將此注解保存在Javadoc中 @Documented // 允許子類繼承父類的注解 @Inherited // 允許一個注解可以被使用一次或者多次 // @Repeatable(value = https://www.cnblogs.com/xiangwang1111/archive/2022/10/14/Object.class) // 標記注解,不包含任何元素 public @interface Test {}
嘗試著舉一個小栗子,比如最常見的,驗證密碼有效性:
/** * 定義注解 * * @author xiangwang */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface UseCase { int id() default -1; String description() default ""; }
可以用兩種方式來看看效果:
1、直接運行注解:
/** * 使用注解 * * @author xiangwang */ public class PasswordUtils { // 使用@UserCase注解 @UseCase(id = 1, description = "密碼必須至少包含一位數字") public static boolean validate(String password) { return (password.matches("\\w*\\d\\w*")); } public static void main(String[] args) { System.out.println(PasswordUtils.validate("w1errd")); } }
2、或者使用昨天介紹的反射來決議注解:
/** * 決議注解 * * @author xiangwang */ public class UseCaseTracker { public static void trackUseCases(List<Integer> useCases, Class<?> cl) { for (Method m : cl.getDeclaredMethods()) { UseCase uc = m.getAnnotation(UseCase.class); if (uc != null) { System.out.println("發現注解id:" + uc.id() + " - 注解description:" + uc.description()); // 剔除已有注解 useCases.remove(Integer.valueOf(uc.id())); } } useCases.forEach(i -> System.out.println("缺少用例id:" + i)); } public static void main(String[] args) { List<Integer> useCases = IntStream.range(1, 5).boxed().collect(Collectors.toList()); trackUseCases(useCases, PasswordUtils.class); } }
這是最最簡單的注解形式,注解真正的用武之地是各類開發框架,尤其是ORM框架,明天就自己嘗試著實作一個:)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/514228.html
標籤:其他
