@data注解不生效_你说啥什么?注解你还不会?
前言:最近有不少粉絲關注本公眾號。并且我已經成功開通了流量主同時會賺一點點廣告費,我打算每個月把這部分錢拿出來給大家買點書刊,算是給大家一點福利吧。大家想買什么書掃描下方的加他拉你加群。最后,非常感謝大家的關注。
一、什么是注解?
Annotaion
注解(Annotaion)是從JDK5.0開始引入的一種新技術稱之為注解機制。
注解(Annotaion)的格式:
注解是以"@注釋名"在代碼中使用的,可以添加一些參數值,例如:@GetMapping("/get")
注解(Annotaion)可以使用的范圍:
當你如果要重寫toString()方法的時候,不是按照規定的名字來寫的話,就會報錯:
正常的話,是不會報錯的:
說明@Override注解帶有檢查的作用。
- @Controller
public class RequestController {
@DeleteMapping("/delete")
@ResponseBody
public String delete(String name,Integer id){
JSONObject json = new JSONObject();
json.put("requestType","deleteType");
json.put("name",name);
json.put("id",id);
return json.toString();
}
} 可以在package、class、method、field等上面使用。例如:
我們可以通過反射機制編程對這些元數據的訪問。
注解有一些特定的功能,例如:
二、內置注解
Java內部定義了一套注解,共有7個:
| @Override | 檢查該方法是否是重寫方法。如果發現其父類,或者是引用的接口中并沒有該方法時,會報編譯錯誤。 |
| @Deprecated | 標記過時方法。如果使用該方法,會報編譯警告。 |
| @SuppressWarnings | 指示編譯器去忽略注解中聲明的警告。 |
作用在其他注解的注解(元注解):在java.lang.annotaion包中
| @Retention | 標識這個注解怎么保存,是只在代碼中,還是編入class文件中,或者是在運行時可以通過反射訪問。 |
| @Documented | 標記這些注解是否包含在用戶文檔中。 |
| @Target | 標記這個注解應該是哪種 Java 成員。 |
| @Inherited | 標記這個注解是繼承于哪個注解類(默認 注解并沒有繼承于任何子類) |
從 Java 7 開始,額外添加了 3 個注解:
| @SafeVarargs | Java 7 開始支持,忽略任何使用參數為泛型變量的方法或構造函數調用產生的警告。 |
| @FunctionalInterface | Java 8 開始支持,標識一個匿名函數或函數式接口。 |
| @Repeatable | Java 8 開始支持,標識某注解可以在同一個聲明上使用多次。 |
三、元注解的使用
(一)前期準備
如果你想自定義注解,那么元注解是必知必會必懂的。
元注解就是注解自定義注解的注解。可能有點饒,一會看例子就明白了,直白點就是給你自定義的注解上一定要加的注解。
作用在其他注解的注解(元注解):在java.lang.annotaion包中
| @Retention | 標識這個注解怎么保存,是只在代碼中,還是編入class文件中,或者是在運行時可以通過反射訪問。 |
| @Documented | 標記這些注解是否包含在用戶文檔中。 |
| @Target | 標記這個注解應該是哪種 Java 成員。 |
| @Inherited | 標記這個注解是繼承于哪個注解類(默認 注解并沒有繼承于任何子類) |
我們定義一個類,類的作用就是用來測試我們定義的注解:
/*** @Auther: truedei
* @Date: 2020 /2020/9/6 18:11
* @Description: 自定義注解測試
*/
public class Test {
}
1
2
3
4
5
6
7
8
然后創建一個類,把class標識符改成@interface:這就是自定義好的注解了。
/*** @Auther: truedei
* @Date: 2020 /2020/9/6 19:00
* @Description: 自定義注解
*/
public @interface MyAnnotaion {
}
現在可以看到就可以使用了,只不過沒有任何的功能:
(二)@Target的用法詳解
我們來賦予一定的功能,來標識這個注解的作用:
加上元注解:@Target,就是用來指出對什么生效,作用的目標是什么,可以在什么地方使用。
可以看到傳遞的是一個E
可以點看@Target的源碼看一下:
可以看到下面這種情況。
需要提前知道的是,value()是接收的參數,并不是一個方法。
那么Target就需要接收一個ElementType[]的數組。
@Documented@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
沒加之前,先改造一下:
可以看到這個注解什么都沒加,既可以加在類上,也可以加在方法上,也可以加在變量上。
如果我們想做限制呢?只允許我們的這個注解對類生效
我們先來看一下Controller注解這個應該不陌生,就不解釋了。
那么我們也可以加上這個:
可以看到效果了,只要類上的生效了,其余的都報錯了。
那么這就是元注解Target的作用。
看一下ElementType.java中枚舉的參數,這些都可以使用,了解下就好。
package java.lang.annotation;public enum ElementType {
TYPE, /* 類、接口(包括注釋類型)或枚舉聲明 */
FIELD, /* 字段聲明(包括枚舉常量) */
METHOD, /* 方法聲明 */
PARAMETER, /* 參數聲明 */
CONSTRUCTOR, /* 構造方法聲明 */
LOCAL_VARIABLE, /* 局部變量聲明 */
ANNOTATION_TYPE, /* 注釋類型聲明 */
PACKAGE /* 包聲明 */
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
如果你想讓你的注解對什么生效,就指定好就OK:
(三)@Retention的用法詳解
Retention中需要傳遞RetentionPolicy。
RetentionPolicy.java有三個枚舉參數,如下:
package java.lang.annotation;public enum RetentionPolicy {
SOURCE, /* Annotation信息僅存在于編譯器處理期間,編譯器處理完之后就沒有該Annotation信息了 */
CLASS, /* 編譯器將Annotation存儲于類對應的.class文件中。默認行為 */
RUNTIME /* 編譯器將Annotation存儲于class文件中,并且可由JVM讀入 */
}
1
2
3
4
5
6
7
8
一般都是調用**RUNTIME**,調用RUNTIME我們可以通過反射拿到相關的數據,來進行處理等。
由于這個不太好驗證,就不一一驗證了,了解就好。
(四)@Documented的用法詳解
如果使用 @Documented 修飾該 Annotation,則表示它可以出現在 javadoc 中。
定義 Annotation 時,@Documented 可有可無;
若沒有定義,則 Annotation 不會出現在 javadoc 中。
(五)@Inherited的用法詳解
子類可以繼承父類的注解。
*** @Auther: truedei
* @Date: 2020 /2020/9/6 19:00
* @Description: 自定義注解
*/
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotaion {
}
四、自定義參數詳解
注解的參數:參數的類型 + 參數名 ();
如果想有默認值還需要加上default 值。
例如:
//自定義參數1String name();
//自定義參數2 帶默認值的
String type() default "";
1
2
3
4
我們給事先定義好的注解類加上一個參數,隨便寫名字即可:
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotaion {
//參數
String name();
}
1
2
3
4
5
6
7
8
9
10
可以看到我們在使用的時候,就會報錯了,原因是必須要給這個定義好的參數傳遞一個值。
我們傳遞過來值:
@MyAnnotaion(name = "鄭暉")public void test(){
}
1
2
3
4
這個時候就有同學要問了:我定義好參數之后,可以不傳遞參數嗎,用到的時候再傳遞。
答案是可以的,如下:設置一個默認值就好了:
String type() default "";1
當然了,也可以傳遞很多類型的參數例如:
import java.lang.annotation.*;
/**
* @Auther: truedei
* @Date: 2020 /2020/9/6 19:00
* @Description: 自定義注解
*/
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotation {
//String類型
String name();
//int類型
int age() default 0;
//boolean類型
boolean bool() default false;
//char 類型
char cha() default ' ';
//各種數組類型
String[] strs() default {};
//枚舉類型
MyEnum myEnum() default MyEnum.A;
}
枚舉類型類定義:
public enum MyEnum {
A,B,C,D;
}
我們在使用的時候,就可以隨心所欲的使用:
/**
* @Auther: truedei
* @Date: 2020 /2020/9/6 18:11
* @Description: 自定義注解測試
*/
public class Test {
String data;
@MyAnnotaion(name = "鄭暉",age = 85,cha = 'A',strs = {"aasd","xsw","你好"},myEnum = MyEnum.C)
public void test(){
}
}
五、利用反射操作注解
MyA.java:
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 MyA {
}
MyAnnotation.java:
import java.lang.annotation.*;
/**
* @Auther: truedei
* @Date: 2020 /2020/9/6 19:00
* @Description: 自定義注解 ---->給特定的方法用的
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
//String類型
String name();
}
Test.java:
/*** @Auther: truedei
* @Date: 2020 /2020/9/6 18:11
* @Description: 自定義注解測試
*/
@MyA
public class Test {
String data;
@MyAnnotation(name = "鄭暉")
public void test(String name){
System.out.println("我的名字:"+name);
}
}
測試類:
package cn.annotaion;import java.lang.annotation.Annotation;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Inherited;
import java.lang.reflect.Method;
/**
*測試類
*/
public class AnnotationTest {
public static void main(String[] args) throws Exception {
//拿到指定的類的Test
Class cl = Class.forName("cn.annotaion.Test");
//判斷是否是我們特定自定義的注解 如果是就掃描
if (cl.isAnnotationPresent(MyA.class)) {
Method[] methods = cl.getMethods();
for (Method method : methods) {
// 判斷 somebody() 方法是否包含MyAnnotation注解
if(method.isAnnotationPresent(MyAnnotation.class)){
// 獲取該方法的MyAnnotation注解實例
MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
// 獲取 myAnnotation的值,并打印出來
String name = myAnnotation.name();
System.out.println(name);
//執行這個方法
method.invoke(new Test(),name);
}
}
}
}
}
運行:
打油詩我不在乎我的作品文章是被現在的人讀還是由子孫后代來讀。既然上帝花了六千年來等一位觀察者,我可以花上一個世紀來等待讀者。?永久激活方案~
2020-07-29
spring 狀態機
2020-05-12
mybatis用到的設計模式
2020-07-02
MySQL索引實現原理分析
2020-05-19
Spring中的用到的設計模式
2020-04-23
Spring 和 SpringBoot 之間到底有啥區別?
2020-05-29
如何快速搭建一個免費的 鑒黃 平臺
2020-08-15
美國也就那么回事吧
2020-08-15
5T的Java視頻教程全部免費獲取
2020-08-14
總結
以上是生活随笔為你收集整理的@data注解不生效_你说啥什么?注解你还不会?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不可用于python编程开发的是_Pyt
- 下一篇: mysql总结 博客园_mysql 总结