注解的实现

1.概念

注解表示一个标识(标注、标记),它可以用在类上、方法上、变量上等,给类的各个组成部分一些额外的表示,能够被编译器识别。

2.常见注解

@Override: 描述一个方法是复写的父类方法
@Deprecate: 描述一个方法是过时的方法,调用过时的方法会有一个横线
@SuppressWarnings(value = “all”): 压制警告:写在类上,则压制整个类的警告,在方法上则压制方法上的警告

3.自定义注解

【在使用注解的时候如果注解里面的属性没有指定默认值,那么我们就需要手动给出注解属性的设置值。】

public @interface Anno {
    //定义一个基本类型的属性
    //public属性类型属性名() default 默认值;
   int a() default 23 "张三";
    //定义一个String类型的属性
    public String name() default 23;
    //定义一个class类型的属性
    public  Class clazz() default  Anno2.class;
    //定义一个注解类型的属性
    public Anno2 anno() default  @Anno2;
    //定义一个枚举类型的属性
    public Week week() default Week.Monday;
    //以上类型的一维数组
    //int 数组
    public int [] arr() default {1,2,3,4,5}
    //枚举数组
    public Week[] weeks() default{Week.Monday}
    public String value();
    //特殊属性value 变量只有一个,则使用时可以省略名称直接赋值
}

//类上使用注解
//在使用注解的时候如果注解里面的属性没有指定默认值,那么我们就需要手动给出注解属性的设置值。
//此处相当于Anno的对象,只是给类或者方法添加了一个标签,不会影响实体
@Anno("李四")
public class Demo1 {
    public static void main(String[] args) {

    }
}
4.元注解

@Target:指定了注解能在哪里使用【成员变量、类、方法】
@Retention:可以理解为保留时间(生命周期)
@lnherited:表示修饰的自定义注解可以被子类继承
@Documented:表示该自定义注解,会出现在API文档里面

//定义特殊属性value
@Retention(RetentionPolicy.RUNTIME) //注解在运行时期有效
@Target(ElementType.TYPE)//注解可以使用在类上
//@Target(ElementType.METHOD)//注解可以使用在方法上
//@Target(ElementType.FIELD)//注解可以使用在成员变量上
@Inherited//表示修饰的自定义注解可以被子类继承
public @interface Anno {
}

//测试类
public class Demo2 {
    public static void main(String[] args) throws ClassNotFoundException {
        //得到类的字节码对象
        Class<?> personClazz = Class.forName("com.itheima3.Person");
        //getAnnotation(Anno.class);得到该类的注解对象
        Anno a1 = personClazz.getAnnotation(Anno.class);
        Class<?> studentClazz = Class.forName("com.itheima3.Student");
        Anno a2 = personClazz.getAnnotation(Anno.class);
        System.out.println(a1==a2);
    }
}

打印结果
true
5.自定义注解实现

测试让有注解的方法执行,没有Test的方法不执行

//自定义注解
//元注解[对注解进一步进行说明]
@Target(ElementType.METHOD)//指定注解可以用在哪些地方
@Retention(RetentionPolicy.RUNTIME)//表示注解的存活时间可以到运行
//定义一个注解
public @interface Test {
}

//方法类
public class UseTest {
    //没有使用Test注解
    public void show(){
        System.out.println("UseTest....show....");
    }
    //使用Test注解
    @Test
    public void method(){
        System.out.println("UseTest....method....");
    }
    //使用Test注解
    @Test
    public void function(){
        System.out.println("UseTest....function....");
    }
}

//测试类
//测试让有注解的方法执行,没有Test的方法不执行
public class AnnoDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //通过反射获取UseTest的字节码文件对象
        Class<?> clazz = Class.forName("com.itheima2.UseTest");
        //2.通过反射获取这个类里面所有方法的对象
        Method[] methods = clazz.getDeclaredMethods();
        //创建对象用于执行方法
        Object o = clazz.getConstructor().newInstance();
        //遍历数组,得到每一个方法对象
        for (Method method : methods) {
            //getAnnotation(Test.class)返回原方法上额外的注解
            Test test = method.getAnnotation(Test.class);
            //如果有注解,就执行
            if (test != null) {
                //注解没有设置存活时间,则打印无结果
                method.invoke(o);
            }
            //method.isAnnotationPresent(Test.class)判断方法上是否有注解,有则返回true
            /*if(method.isAnnotationPresent(Test.class)){
                method.invoke(o);
            }*/
        }
    }
}

打印结果:
-------------------------------------------------------------------------------
UseTest....method....
UseTest....function....
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Java中,我们可以使用自定义注解实现AOP(面向切面编程)。AOP是一种编程范型,它允许开发者在程序运行时动态地将代码切入到已有代码的特定位置。 下面是一个简单的示例,演示如何使用自定义注解实现AOP。 首先,我们需要定义一个自定义注解: ``` @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Loggable { } ``` 这个注解用来标记需要记录日志的方法。它的@Target注解指定了它只能用于方法上,@Retention注解指定了它的生命周期是运行时。 接下来,我们创建一个切面类,用来实现AOP的逻辑: ``` @Aspect @Component public class LoggingAspect { @Before("@annotation(com.example.Loggable)") public void logMethodCall(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("Method " + methodName + " called"); } } ``` 这个类使用Spring AOP框架提供的@Aspect注解来标记它是一个切面类。它的@Before注解指定了它要在被@Loggable注解标记的方法之前执行。JoinPoint参数包含了被拦截的方法的信息,我们可以从中获取方法名等信息。 最后,在需要记录日志的方法上加上@Loggable注解即可: ``` @Component public class MyService { @Loggable public void doSomething() { // do something } } ``` 当doSomething()方法被调用时,LoggingAspect中的logMethodCall()方法会被执行,记录方法调用信息。 这就是使用自定义注解实现AOP的基本步骤。当然,实际应用中会更加复杂,需要更多的切面逻辑和注解参数等。但是这个简单的示例可以帮助你理解如何使用自定义注解实现AOP。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陪雨岁岁年年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值