1 アノテーション
アノテーションは非常に強力で、Java コードを強化すると同時に、リフレクション技術を使用して多くの機能を拡張および実現できます。これらは 3 つの主要なフレームワークの最下層で広く使用されています。
従来は XML テキスト ファイルを通じて宣言していましたが (ただし、XML は扱いにくく、チェックが困難です)、現在では、コード量が少なく、フレームワークが自動的に生成できるアノテーションに基づいた開発が最も主流になっています。アノテーションに基づく多くのコードによりコード量が削減され、プログラムがより読みやすくなります。たとえば、最も人気のある SpringBoot は完全にアノテーション テクノロジに基づいています。
注釈のデザインは非常に繊細で、最初に学んだときは代替的、あるいは冗長、あるいはゴミのようにさえ感じました。Java コードがあるのに @ アノテーションが必要なのはなぜですか? しかし、熟練すると、Java コードの機能を超え、Java コードを即座に強力にすることができることに驚かれるでしょう。ゆっくり体験してみましょう。
2 アノテーションの分類
注釈は 3 つのカテゴリに分類されます。まず、それらについて理解しましょう。
JDK にはアノテーション
メタアノテーション
カスタム アノテーションが付属しています
2.1 JDK アノテーション
JDK アノテーションには 5 つのアノテーションしかありません。
@Override :用来标识重写方法
@Deprecated マークは、このメソッドが古いことを示しますが、私はそれを使用します。期限切れであることを思い出させないでください@SuppressWarnings("deprecation") 警告を無視してください
@SafeVarargs jdk1.7 が表示されます。ヒープ汚染、一般的には使用されません
@ FunctionallInterface jdk1.8 登場、連携 関数型プログラミングのラムダ式、あまり使われない
2.2 メタアノテーション
注釈の説明に使用される注釈は 5 つだけです。
@Target 注解用在哪里:类上、方法上、属性上等等
@Retention 注解的生命周期:源文件中、字节码文件中、运行中
@Inherited により、サブアノテーションが
@Documented を継承できるようになります Javadoc の生成時にアノテーションが組み込まれます @Repeatable アノテーションは、
同じ場所で複数回使用できる反復可能なタイプのアノテーションとしては一般的には使用されません。
2.2.1 @ターゲット要素タイプ…
注釈が存在する場所を説明します。
ElementType.TYPE はクラス要素に適用されます
ElementType.METHOD はメソッド レベルに適用されます
ElementType.FIELD はフィールドまたはプロパティ (メンバー変数) に適用されます ElementType.ANNOTATION_TYPE は
注釈タイプに適用されます
ElementType.CONSTRUCTOR はコンストラクタに適用されます
ElementType.LOCAL_VARIABLE はローカル変数に適用されます
ElementType.PACKAGE が適用されますElementType.PARAMETER はパッケージ宣言に
適用されます。 ElementType.PARAMETER はメソッドのパラメーターに適用されます。
2.2.2 @Retention RetentionPolicy…
このアノテーションは、カスタム アノテーションが保持される期間を定義します。たとえば、一部のアノテーションはソース コードにのみ表示され、コンパイラによって破棄されますが、他のアノテーションはクラス ファイル内でコンパイルされます。クラス ファイル内でコンパイルされたアノテーションは、コンパイラによって無視される場合があります。仮想マシン、その他はクラスのロード時に読み取られます。
なぜバイトコードファイルの有無で分けるのでしょうか?時間がないと反射技術が利用できないため、識別して処理することができません。これには 3 つの値があります。
SOURCE はソース ファイル内で有効です (つまり、ソース ファイルは保存されます)
CLASS はクラス ファイル内で有効です (つまり、クラスは保存されます)
RUNTIME は実行時に有効です (つまり、ランタイムは保存されます)
3 カスタム注釈
注: アノテーションの構文は通常の Java の構文とは異なります
パッケージの作成: cn.tedu.annotation
クラスの作成: TestAnnotation.java
package cn.tedu.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*本类用于完成自定义注解*/
public class TestAnnotation {
}
//2.通过@Target注解标记自定义注解的使用位置
/*3.通过元注解@Target规定自定义注解可以使用的位置
* 我们使用"ElementType.静态常量"的方式来指定自定义注解具体可以加在什么位置
* 而且,值可以写多个,格式:@Target({ElementType.XXX,ElementType.XXX}*/
@Target({
ElementType.METHOD,ElementType.TYPE})//可以加在方法&类上
//3.通过@Retention注解标记自定义注解的生命周期
/*4.通过元注解@Retention规则自定义注解的生命周期
* 我们使用"RetentionPolicy.静态常量"的方式来指定自定义注解的生命周期
* 注意:值只能写一个:SOURCE CLASS RUNTIME 3选1 */
@Retention(RetentionPolicy.RUNTIME)//到运行时都有效
//1.定义自定义注解
/*1.首先注意:注解定义的语法与Java不同
* 2.定义自定义注解的格式:@interface 注解名*/
@interface Rice{
//5.我们可以给注解进行功能增强--添加注解的属性
/*5.注意:int age();不是方法的定义,而是给自定义注解添加了一个age属性*/
//int age();//给自定义注解添加一个普通属性age,类型是int
int age() default 0;//给自定义注解的普通属性赋予默认值0
/*6.注解中还可以添加特殊属性value
* 特殊属性的定义方式与普通属性一样,主要是使用方式不同
* 注意:特殊属性的名字必须叫value,但是类型不做限制
* 特殊属性也可以赋予默认值,格式与普通属性一样,不能简写
* */
//String value();//定义一个特殊属性value,类型是String
String value() default "Lemon";//定义特殊属性并给特殊属性赋予默认值
}
//4.定义一个类用来测试自定义注解
//@Rice
class TestAnno{
/*测试1:分别给TestAnno类 name属性 eat方法都添加Rice注解
* 结论:属性上的注解报错了,说明自定义注解可以加在什么位置,由@Target决定*/
//@Rice//报错了
String name;
/*测试2:当我们给Rice注解添加了一个age属性以后,@Rice注解使用时直接报错
* 结论:当注解没有定义属性时,可以直接使用
* 当注解定义了属性以后,必须给属性赋值,格式:@Rice(age = 10)*/
/*测试3:给age属性赋予默认值以后,可以直接使用@Rice注解
* 不需要给age属性赋值,因为age属性已经有默认值0了*/
/*测试4:给Rice注解添加了特殊属性value以后,必须给属性赋值
* 只不过特殊属性赋值时可以简写成 @Rice("Apple")
* 测试5:如果特殊属性也赋予了默认值,那么可以直接使用这个注解
* 如果要给注解的所有属性赋值,每条赋值都不能简写*/
@Rice(age=10,value="orange")
//@Rice("Apple")
//@Rice(age = 10)
//@Rice(10)//报错,不可以简写,普通属性没有这种格式
public void eat(){
System.out.println("干饭不积极,思想有问题");
}
}
おめでとうございます。もう 1 つのレベルに合格しました。フォローアップ フレームワーク部分では注釈を頻繁に使用します。良いスタートが切れることを願っています。