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

Java8新特性之重復注解與類型注解詳解

 更新時間:2021年09月07日 10:54:52   作者:冰 河  
這篇文章主要使介紹了Java8新特性重復注解與類型注解,文章還介紹了JDK5中的注解與之對比,感興趣的朋友可以參考下面具體文章內(nèi)容

Java8新特性重復注解與類型注解

在Java8之前,在某個類或者方法,字段或者參數(shù)上標注注解時,同一個注解只能標注一次。但是在Java8中,新增了重復注解和類型注解,也就是說,從Java8開始,支持在某個類或者方法,字段或者參數(shù)上標注多個相同的注解。那么,有讀者就會問了:如何實現(xiàn)呢?別急,往下看!文中不只是Java8中的注解。

一、JDK5中的注解

1.注解(@)

注解就相當于一種標記,在程序中加了注解就等于為程序加了某種標記。(JDK1.5新特性)。

2.作用

告訴javac編譯器或者java開發(fā)工具……向其傳遞某種信息,作為一個標記。

3.如何理解注解?

一個注解就是一個類。

標記可以加在包、類、字段、方法,方法參數(shù)以及局部變量上??梢酝瑫r存在多個注解。

每一個注解結(jié)尾都沒有“;”或者其他特別符號。

定義注解需要的基礎注解信息如下所示。

@SuppressWarnings("deprecation")  //編譯器警告過時(source階段)
@Deprecated      //過時(Runtime階段)
@Override      //重寫(source階段)
@Retention(RetentionPolicy.RUNTIME) 
//保留注解到程序運行時。(Runtime階段)
@Target({ElementType.METHOD,ElementType.TYPE})
//標記既能定義在方法上,又能定義在類、接口、枚舉上等。

注意:

1)添加注解需要有注解類。RetentionPolicy是一個枚舉類(有三個成員)。

2)Target中可以存放數(shù)組。它的默認值為任何元素。

  • ElementType.METHOD:表示只能標記在方法上。
  • ElementType.TYPE:表示只能標記定義在類上、接口上、枚舉上等

3)ElementType也是枚舉類。成員包括:ANNOTATION_TYPE(注解)、CONSTRUCTOR(構(gòu)造方法)、FIEID(成員變量)、LOCAL_VARIABLE(變量)、METHOD(方法)、PACKAGE(包)、PARAMETER(參數(shù))、TYPE。

4.關于注解

  • 元注解:注解的注解(理解:給一個注解類再加注解)
  • 元數(shù)據(jù):數(shù)據(jù)的數(shù)據(jù)
  • 元信息:信息的信息

5.注解分為三個階段

java源文件–> class文件 --> 內(nèi)存中的字節(jié)碼。

Retention的注解有三種取值:(分別對應注解的三個階段)

  • RetentionPolicy.SOURCE
  • RetentionPolicy.CLASS
  • RetentionPolicy.RUNTIME

注意:注解的默認階段是Class。

6.注解的屬性類型

原始類型(就是八個基本數(shù)據(jù)類型)、String類型、Class類型、數(shù)組類型、枚舉類型、注解類型。

7.為注解增加屬性

value:是一個特殊的屬性,若在設置值時只有一個value屬性需要設置或者其他屬性都采用默認值時 ,那么value=可以省略,直接寫所設置的值即可。

例如:

@SuppressWarnings("deprecation")

為屬性指定缺省值(默認值):

例如:

String value() default "blue"; //定義在注解類中

數(shù)組類型的屬性:

例如:

int[] arrayArr() default {3,4,5,5};//定義在注解類中
SunAnnotation(arrayArr={3,9,8}) //設置數(shù)組值


注意:如果數(shù)組屬性中只有一個元素時,屬性值部分可以省略大括號。

例如:

SunAnnotation(arrayArr=9)

枚舉類型的屬性:
例如:

EnumDemo.TrafficLamp lamp()

枚舉類型屬性, 定義在注解類中,這里使用了自定義的枚舉類EnumDemo.java并沒有給出相關代碼,這里只是舉個例子

default EnumDemo.TrafficLamp.RED;

注解類型的屬性:
例如:

MetaAnnotation annotationAttr()
//定義在一個注解類中,并指定缺省值,
//此屬性關聯(lián)到注解類:MetaAnnotation.java, 
default @MetaAnnotation("lhm");
//設置注解屬性值
@SunAnnotation(annotationAttr=@MetaAnnotation("flx"))

二、Java8中的注解

對于注解(也被稱做元數(shù)據(jù)),Java 8 主要有兩點改進:類型注解和重復注解。

1.類型注解

1)Java 8 的類型注解擴展了注解使用的范圍。

在java 8之前,注解只能是在聲明的地方所使用,java8開始,注解可以應用在任何地方。

例如:

創(chuàng)建類實例

new @Interned MyObject();

類型映射

myString = (@NonNull String) str;

implements 語句中

class UnmodifiableList<T> implements@Readonly List<@Readonly T> { ... }

throw exception聲明

void monitorTemperature() throws@Critical TemperatureException { ... }

注意:

在Java 8里面,當類型轉(zhuǎn)化甚至分配新對象的時候,都可以在聲明變量或者參數(shù)的時候使用注解。
Java注解可以支持任意類型。

類型注解只是語法而不是語義,并不會影響java的編譯時間,加載時間,以及運行時間,也就是說,編譯成class文件的時候并不包含類型注解。

2)新增ElementType.TYPE_USE 和ElementType.TYPE_PARAMETER(在Target上)

新增的兩個注釋的程序元素類型 ElementType.TYPE_USE 和 ElementType.TYPE_PARAMETER用來描述注解的新場合。

  • ElementType.TYPE_PARAMETER 表示該注解能寫在類型變量的聲明語句中。
  • ElementType.TYPE_USE 表示該注解能寫在使用類型的任何語句中(例如:聲明語句、泛型和強制轉(zhuǎn)換語句中的類型)。

例如,下面的示例。

@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
@interface MyAnnotation {}

3)類型注解的作用

類型注解被用來支持在Java的程序中做強類型檢查。配合第三方插件工具Checker Framework(注:此插件so easy,這里不介紹了),可以在編譯的時候檢測出runtime error(例如:UnsupportedOperationException; NumberFormatException;NullPointerException異常等都是runtime error),以提高代碼質(zhì)量。這就是類型注解的作用。

注意:使用Checker Framework可以找到類型注解出現(xiàn)的地方并檢查。

例如下面的代碼。

import checkers.nullness.quals.*;
public class TestDemo{
    void sample() {
        @NonNull Object my = new Object();
    }
}

使用javac編譯上面的類:(當然若下載了Checker Framework插件就不需要這么麻煩了)

javac -processor checkers.nullness.NullnessChecker TestDemo.java

上面編譯是通過的,但若修改代碼:

@NonNull Object my = null;

但若不想使用類型注解檢測出來錯誤,則不需要processor,正常javac TestDemo.java是可以通過編譯的,但是運行時會報 NullPointerException 異常。

為了能在編譯期間就自動檢查出這類異常,可以通過類型注解結(jié)合 Checker Framework 提前排查出來錯誤異常。

注意java 5,6,7版本是不支持注解@NonNull,但checker framework 有個向下兼容的解決方案,就是將類型注解@NonNull 用/**/注釋起來。

import checkers.nullness.quals.*;
public class TestDemo{
    void sample() {
        /*@NonNull*/ Object my = null;
    }
}

這樣javac編譯器就會忽略掉注釋塊,但用checker framework里面的javac編譯器同樣能夠檢測出@NonNull錯誤。
通過 類型注解 + checker framework 可以在編譯時就找到runtime error。

2.重復注解

允許在同一聲明類型(類,屬性,或方法)上多次使用同一個注解。

Java8以前的版本使用注解有一個限制是相同的注解在同一位置只能使用一次,不能使用多次。

Java 8 引入了重復注解機制,這樣相同的注解可以在同一地方使用多次。重復注解機制本身必須用 @Repeatable 注解。

實際上,重復注解不是一個語言上的改變,只是編譯器層面的改動,技術(shù)層面仍然是一樣的。

例如,我們可以使用如下示例來具體對比Java8之前的版本和Java8中的注解。

**1)**自定義一個包裝類Hints注解用來放置一組具體的Hint注解

@interface MyHints {
    Hint[] value();
}
 
@Repeatable(MyHints.class)
@interface Hint {
    String value();
}

使用包裝類當容器來存多個注解(舊版本方法)

@MyHints({@Hint("hint1"), @Hint("hint2")})
class Person {}

使用多重注解(新方法)

@Hint("hint1")
@Hint("hint2")
class Person {}

**2)**完整類測試如下所示。

public class RepeatingAnnotations {
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Filters {
        Filter[] value();
    }
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(Filters.class)
    public @interface Filter {
        String value();
    }
    @Filter("filter1")
    @Filter("filter2")
    public interface Filterable {
    }
    public static void main(String[] args) {
        for (Filter filter : Filterable.class.getAnnotationsByType(Filter.class)) {
            System.out.println(filter.value());
        }
    }
}

輸出結(jié)果:

filter1
filter2

分析:

注釋Filter被@Repeatable( Filters.class )注釋。Filters 只是一個容器,它持有Filter, 編譯器盡力向程序員隱藏它的存在。通過這樣的方式,F(xiàn)ilterable接口可以被Filter注釋兩次。

另外,反射的API提供一個新方法getAnnotationsByType() 來返回重復注釋的類型(注意Filterable.class.getAnnotation( Filters.class )將會返回編譯器注入的Filters實例。

**3)**java 8之前也有重復使用注解的解決方案,但可讀性不好。

public @interface MyAnnotation {  
     String role();  
}  
 
public @interface Annotations {  
    MyAnnotation[] value();  
}  
 
public class RepeatAnnotationUseOldVersion {  
    @Annotations({@MyAnnotation(role="Admin"),@MyAnnotation(role="Manager")})  
    public void doSomeThing(){  
    }  
}

Java8的實現(xiàn)方式(由另一個注解來存儲重復注解,在使用時候,用存儲注解Authorities來擴展重復注解),可讀性更強。

@Repeatable(Annotations.class) 
public @interface MyAnnotation {  
     String role();  
}  
 
public @interface Annotations {  
    MyAnnotation[] value();  
}  
 
public class RepeatAnnotationUseOldVersion {  
 @MyAnnotation(role="Admin")  
    @MyAnnotation(role="Manager")
    public void doSomeThing(){  
    }  
} 

什么?沒看懂?那就再來一波!??!

三、Java8對注解的增強

Java 8對注解處理提供了兩點改進:可重復的注解及可用于類型的注解??傮w來說,比較簡單,下面,我們就以實例的形式來說明Java8中的重復注解和類型注解。

首先,我們來定義一個注解類BingheAnnotation,如下所示。

package io.mykit.binghe.java8.annotition;

import java.lang.annotation.*;

/**
 * @author binghe
 * @version 1.0.0
 * @description 定義注解
 */
@Repeatable(BingheAnnotations.class)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.LOCAL_VARIABLE,ElementType.TYPE_PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface BingheAnnotation {
    String value();
}

注意:在BingheAnnotation注解類上比普通的注解多了一個@Repeatable(BingheAnnotations.class)注解,有小伙伴會問:這個是啥啊?這個就是Java8中定義可重復注解的關鍵,至于BingheAnnotations.class,大家別急,繼續(xù)往下看就明白了。

接下來,咱們定義一個BingheAnnotations注解類,如下所示。

package io.mykit.binghe.java8.annotation;

import java.lang.annotation.*;

/**
 * @author binghe
 * @version 1.0.0
 * @description 定義注解
 */
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.LOCAL_VARIABLE,ElementType.TYPE_PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface BingheAnnotations {
    BingheAnnotation[] value();
}

看到這里,大家明白了吧?。]錯,BingheAnnotations也是一個注解類,它相比于BingheAnnotation注解類來說,少了一個@Repeatable(BingheAnnotations.class)注解,也就是說,BingheAnnotations注解類的定義與普通的注解幾乎沒啥區(qū)別。值得注意的是,我們在BingheAnnotations注解類中,定義了一個BingheAnnotation注解類的數(shù)組,也就是說,在BingheAnnotations注解類中,包含有多個BingheAnnotation注解。所以,在BingheAnnotation注解類上指定@Repeatable(BingheAnnotations.class)來說明可以在類、字段、方法、參數(shù)、構(gòu)造方法、參數(shù)上重復使用BingheAnnotation注解。

接下來,我們創(chuàng)建一個Binghe類,在Binghe類中定義一個init()方法,在init方法上,重復使用@BingheAnnotation注解指定相應的數(shù)據(jù),如下所示。

package io.mykit.binghe.java8.annotation;

/**
 * @author binghe
 * @version 1.0.0
 * @description 測試注解
 */
@BingheAnnotation("binghe")
@BingheAnnotation("class")
public class Binghe {

    @BingheAnnotation("init")
    @BingheAnnotation("method")
    public void init(){

    }
}

到此,我們就可以測試重復注解了,創(chuàng)建類BingheAnnotationTest,對重復注解進行測試,如下所示。

package io.mykit.binghe.java8.annotation;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author binghe
 * @version 1.0.0
 * @description 測試注解
 */
public class BingheAnnotationTest {

    public static void main(String[] args) throws NoSuchMethodException {
        Class<Binghe> clazz = Binghe.class;
        BingheAnnotation[] annotations = clazz.getAnnotationsByType(BingheAnnotation.class);
        System.out.println("類上的重復注解如下:");
        Arrays.stream(annotations).forEach((a) -> System.out.print(a.value() + " "));

        System.out.println();
        System.out.println("=============================");

        Method method = clazz.getMethod("init");
        annotations = method.getAnnotationsByType(BingheAnnotation.class);
        System.out.println("方法上的重復注解如下:");
        Arrays.stream(annotations).forEach((a) -> System.out.print(a.value() + " "));
    }
}

運行main()方法,輸出如下的結(jié)果信息。

類上的重復注解如下:
binghe class 
=============================
方法上的重復注解如下:
init method 

以上就是Java8新特性之重復注解與類型注解詳解的詳細內(nèi)容,更多關于Java8新特性重復注解與類型注解的資料請關注腳本之家其它相關文章!希望大家以后多多支持腳本之家!

最后,附上Java8新特性核心知識圖,祝大家在學習Java8新特性時少走彎路。

相關文章

  • Idea去除方法形參參數(shù)提示的操作

    Idea去除方法形參參數(shù)提示的操作

    這篇文章主要介紹了Idea去除方法形參參數(shù)提示的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • Java Spring 聲明式事務詳解

    Java Spring 聲明式事務詳解

    這篇文章主要介紹了spring 聲明式事務實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2021-09-09
  • Springboot如何獲取配置文件application.yml中自定義的變量并使用

    Springboot如何獲取配置文件application.yml中自定義的變量并使用

    這篇文章主要介紹了Springboot中獲取配置文件(application.yml)中自定義的變量并使用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • java 泛型的詳解及實例

    java 泛型的詳解及實例

    這篇文章主要介紹了java 泛型的詳解及實例的相關資料,希望通過本文大家能徹底掌握泛型的使用方法,需要的朋友可以參考下
    2017-08-08
  • SpringBoot整合MyBatisPlus詳解

    SpringBoot整合MyBatisPlus詳解

    這篇文章詳細介紹了SpringBoot整合mybatisplus的全過程,文中有詳細的代碼示例,具有一定的參考價值,需要的朋友可以參考一下
    2023-04-04
  • Spring Cloud Alibaba Nacos Config進階使用

    Spring Cloud Alibaba Nacos Config進階使用

    這篇文章主要介紹了Spring Cloud Alibaba Nacos Config進階使用,文中使用企業(yè)案例,圖文并茂的展示了Nacos Config的使用,感興趣的小伙伴可以看一看
    2021-08-08
  • Kotlin Coroutines執(zhí)行異步加載示例詳解

    Kotlin Coroutines執(zhí)行異步加載示例詳解

    這篇文章主要給大家介紹了關于Kotlin Coroutines執(zhí)行異步加載的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2018-01-01
  • spring boot中controller的使用及url參數(shù)的獲取方法

    spring boot中controller的使用及url參數(shù)的獲取方法

    這篇文章主要介紹了spring boot中controller的使用及url參數(shù)的獲取方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2018-01-01
  • 通過代碼實例解析JAVA類生命周期

    通過代碼實例解析JAVA類生命周期

    這篇文章主要介紹了通過代碼實例解析JAVA類生命周期,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • 多個sheet Excel 數(shù)據(jù)導入數(shù)據(jù)庫的實現(xiàn)方法

    多個sheet Excel 數(shù)據(jù)導入數(shù)據(jù)庫的實現(xiàn)方法

    這篇文章主要介紹了多個sheet Excel 數(shù)據(jù)導入數(shù)據(jù)庫的實現(xiàn)方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03

最新評論