浅析Java注解

浅析Java注解

这几天需要使用自定义注解,发现很不熟练,写此笔记总结
参考慕课网教程。
JDK1.8

前言

注解的概念

        Java提供了一种原程序中的元素关联任何信息和任何数据的途径和方法。

通俗理解:注解本身没有任何实质功能,和xml用途上基本一样,都是一种元数据,一种解释数据,声明属性的方式。所以理论上注解可以取代xml配置(现在也流行这么做)。

注解的分类

1.按照运行机制分类解释
源码注解只在源码中存在 ,编译为.class就没有了
编译时注解在源码和.class都存在
运行时注解在运行阶段还会起作用,会影响运行逻辑

2.按照来源分类
来自JDK
来自第三方
自定义

2.元注解注解的注解(见下文)

(重点)自定义注解

语法要求

import java.lang.annotation.*;

/**
 * Created by slgxmh on 16-6-8.
 */
//成员类型时受限制的,仅有String,Class,Annotation,Enumeration和基础类型
//如果注解只有一个成员,成员名约定俗成为value(),在使用时可以忽略成员名和赋值号(=)
//注解类可以没有成员,没有成员的注解成为标识注解

//下面四行称为元注解
@Target(ElementType.METHOD)//作用域
@Retention(RetentionPolicy.RUNTIME)//生命周期
@Inherited//允许子类继承
@Documented//生成javadoc时会包含注解
public @interface Description {//注解使用@interface关键字定义

    String name();//成员应为无参无异常

    int age() default 8;//声明默认值的方式
}
注:1.作用域包含以下声明

这里写图片描述

名称解释
METHOD方法
ANNOTATION_TYPE注解类
CONSTRUCTOR构造方法声明
FIELD字段声明
LOCAL_VARIABLE局部变量声明
PACKAGE包声明
PARAMETER参数声明
TYPE类,接口
注:2.生命周期包含以下声明

这里写图片描述

名称解释
RUNTIME运行时存在,可以通过反射读取
CLASS编译时记录,运行时忽略
SOURCE只在源码显示,编译时会丢弃

使用一个自定义注解

使用方式:

@<注解名>(<成员名1>=<成员值1>,<成员名2>=<成员名2>,…)

例(使用上面的自定义注解):
@Description(name = "小明", age = 10)//使用自己定义的注解(请注意作用域为方法)
public String sayHello() {
    return "hello";
}

例(类注解)

我们有一个注解如下

@Target(ElementType.TYPE)//注意作用域为TYPE
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {

    String name();

    int age() default 8;
}

类为下

@Description(name = "小明")
public class XiaoMing {
    public String sayHello() {
        return "hello";
    }
}

我们运行一下

public static void main(String[] args) {
        try {
            //加载类
            Class c = Class.forName("com.learn.annotation.XiaoMing");
            //拿到注解(是否存在Description.class这个注解)
            if (c.isAnnotationPresent(Description.class)) {
                //拿到注解实例
                Description d = (Description) c.getAnnotation(Description.class);
                System.out.println(d.name() + ":" + d.age());
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

我们可以看到控制台输出小明:8(默认age为8)

例(方法注解)

我们将上面的注解类型变为METHOD,注解使用如下

public class XiaoMing {
    @Description(name = "小明")
    public String sayHello() {
        return "hello";
    }
}

主函数如下

public static void main(String[] args) {
        try {
            //加载类
            Class c = Class.forName("com.learn.annotation.XiaoMing");
            //找到方法上的注解
            Method[] methods = c.getMethods();
            for (Method m : methods) {
                if (m.isAnnotationPresent(Description.class)) {
                    Description d = (Description) m.getAnnotation(Description.class);
                    System.out.println(d.name() + ":" + d.age());
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

我们可以看到控制台输出小明:8
但是要是我们有很多注解呢?主函数如下

public static void main(String[] args) {
        try {
            //加载类
            Class c = Class.forName("com.learn.annotation.XiaoMing");
            //找到方法上的注解
            Method[] methods = c.getMethods();
            for (Method m : methods) {
                Annotation[] annotations = m.getAnnotations();
                for (Annotation a : annotations) {
                    if (a instanceof Description) {
                        Description d = (Description) a;
                        System.out.println(d.name() + ":" + d.age());
                    }
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

我们仍然可以看见小明:8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值