Java注解基础学习笔记

Java注解基础学习笔记

1.注解基本概念

  注解是一种引用数据类型,它编译后的文件是.class文件。注解的基本用法是@注解类型名(参数赋值),注解的作用范围可以是类,域,方法,构造函数,局部变量等,不过特定的注解的作用范围需要看该注解的具体规定。

  了解注解基础对后期注解开发有很大的帮助。



2.JDK1.8常见的注解

2.1@Override

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

  该注解只能放在方法上,用于编译阶段判定该方法是不是对父类或是接口重写的方法,这样可以避免程序员打错字或是对不存在的方法进行重写。



2.2@Deprecated

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

  该注解主要表示构造函数,域,方法等是否已经过期。过期不代表不能使用。如果使用,则会在代码中出现删除线,编译时会有警告。

在这里插入图片描述

在这里插入图片描述



2.3元注解

  元注解就是注解的注解,常见的有@Target和@Retention。前者表示注解的范围,后者表示注解保存的地方。

@Target

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

该元注解里面有一个value属性,它表示被@Target修饰的注解的作用范围,比如类上或是构造函数上等

ElementType的类型如下所示

ElementType

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

@Retention

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

该元注解有一个value属性,该值表示被@Retention修饰的注解最终存在的位置。

RetentionPolicy类型如下:

RetentionPolicy

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

其中

  1. SOURCE表示被@Retention修饰的注解只能保存在源代码中,并不能存储到class文件中,比如@Override。
  2. CLASS表示被@Retention修饰的注解能存储到class文件中。
  3. RUNTIME表示表示被@Retention修饰的注解能存储到class文件中,而且还能在运行时被反射。


3.自定义注解

3.1基本格式

[可见性修饰符] @interface 自定义注解名{
    
    属性1;
    属性2;
    属性3;
}



3.2关于属性

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String value();
    //设置默认值  
//    String name() default “Lord_Bao";
}

@MyAnnotation("lord_bao")
class TestMyAnnotation{


    public static void main(String[] args) {

    }
}
  1. 属性的类型范围
    • 8大基本类型:byte short int long float double boolean char
    • Class String
    • 枚举类型
    • 上述类型的数组形式
  2. 在外部用注解的时候,必须要对相应的属性进行设值。不过可以在注解类里面自己设置默认值。
  3. 特殊情况:当注解类里面只有一个value属性的时候,在外部使用注解的时候可以不用显式写value。
  4. 特殊情况:当属性是数组的形式且该数组只有一个元素的时候,可以不用写{}



4.反射+注解创建对象

场景描述

通过反射,创建自定义类的对象实例。
要求 该类必须被 @MyBean修饰
其次 该类必须要有一个id域,且该id域要被@MyValue注解修饰 并赋值

MyBean

package com.lordbao.DIYAnnotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author Lord_Bao
 * @Date 2020/9/14 14:32
 * @Version 1.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyBean {
}

MyValue

package com.lordbao.DIYAnnotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author Lord_Bao
 * @Date 2020/9/14 14:33
 * @Version 1.0
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyValue {

    int value();
}

自定义的Student类

@MyBean
class Student{

    @MyValue(1)
    private  int id;

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                '}';
    }
}

测试代码

package com.lordbao.DIYAnnotation;

import java.lang.reflect.Field;

/**
 * @Author Lord_Bao
 * @Date 2020/9/14 14:35
 * @Version 1.0
 *
 * 场景模拟:
 *
 * 通过反射,创建自定义类的对象实例。
 * 要求 该类必须被 @MyBean修饰
 * 其次 该类必须要有一个id域,且该id域要被@MyValue注解修饰 并赋值
 *
 *
 */
public class TestDIYAnnotation {

    public static void main(String[] args) throws Exception {
        Class studentClass = Class.forName("com.lordbao.DIYAnnotation.Student");

        //判断studentClass 是不是被自定义的注解修饰
        if (studentClass.isAnnotationPresent(MyBean.class)){
            Student student = (Student) studentClass.newInstance();

            Field idField = studentClass.getDeclaredField("id");
            idField.setAccessible(true);
            //判断idField是否被自定义的注解修饰
            if (idField.isAnnotationPresent(MyValue.class)){
                //value()方法  与  MyValue类的value对应
                int id = idField.getAnnotation(MyValue.class).value();
                idField.set(student,id);

                System.out.println(student);
            }else {
                throw  new  Exception("该类的id没有被@MyValue注解修饰,无法实例化该对象");
            }
        }else {
            throw  new  Exception("该类没有被@MyBean注解修饰,无法实例化该对象");
        }

    }
}

结果

Student{id=1}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值