java注解使用及使用注解实现观察者模式

    为什么要学习注解呢?是因为之前我们学习过观察者模式,发现在声明观察者接口,而且要去实现它,同时这样的观察者只能观察一种类型的东西,如果我们能监听多种类型,比如:观察者A 接口里面有观察方法 onUpdateA ,观察者B接口里面有观察方法onUpdateB,那么同时向Subject注册就比较麻烦,或者有没有一种比较方便的方法,让我们能不用注册,直接想指定什么方法为观察者方法就可以直接调用。其实java里面提供这样的方式实现:注解。

    下面我们先来看一下什么是注解。从名字上看是注释,解释。但功能却不仅仅是注释那么简单。注解(Annotation) 为我们在代码中添加信息提供了一种形式化的方法,是我们可以在稍后 某个时刻方便地使用这些数据(通过 解析注解 来使用这些数据),常见的作用有以下几种:

1.生成文档。这是最常见的,也是java 最早提供的注解。常用的有@see @param @return 等;
2.跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量;
3.在编译时进行格式检查。如@Override放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出;
4.在运行时也能检查到的注解。

包 java.lang.annotation 中包含所有定义自定义注解所需用到的原注解和接口。如接口 java.lang.annotation.Annotation 是所有注解继承的接口,并且是自动继承,不需要定义时指定,类似于所有类都自动继承Object。

注解的使用:
 一.定义注解类:
package javaAuto;

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

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE,ElementType.FIELD,ElementType.CONSTRUCTOR})
public @interface TestA {
    String name();
    int id() default 0;
    Class gid();
}
二.使用注解   
package javaAuto;

import java.util.HashMap;
import java.util.Map;

@TestA(name = "type", gid = Long.class)
// 类成员注解
public class UserAnnotation {
    @TestA(name = "param", id = 1, gid = Long.class)
    // 类成员注解
    private Integer age;

    @TestA(name = "construct", id = 2, gid = Long.class)
    // 构造方法注解
    public UserAnnotation() {
    }

    @TestA(name = "public method", id = 3, gid = Long.class)
    // 类方法注解
    public void a() {
        Map m = new HashMap(0);
    }

    @TestA(name = "protected method", id = 4, gid = Long.class)
    // 类方法注解
    protected void b() {
        Map m = new HashMap(0);
    }

    @TestA(name = "private method", id = 5, gid = Long.class)
    // 类方法注解
    private void c() {
        Map m = new HashMap(0);
    }

    public void b(Integer a) {
    }
}
三.获取注解信息
   
package javaAuto;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ParseAnnotation {

    public static void parseTypeAnnotation() throws ClassNotFoundException {
        Class clazz = Class.forName("javaAuto.UserAnnotation");

        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            TestA testA = (TestA) annotation;
            System.out.println("id= ; gid = " + testA.gid());
        }
    }

    public static void parseMethodAnnotation() {
        Method[] methods = UserAnnotation.class.getDeclaredMethods();
        for (Method method : methods) {

            boolean hasAnnotation = method.isAnnotationPresent(TestA.class);
            if (hasAnnotation) {

                TestA annotation = method.getAnnotation(TestA.class);
                System.out.println("method = " + method.getName() + " ; id = " + annotation.id()
                        + " ; description = " + annotation.name() + "; gid= " + annotation.gid());
            }
        }
    }

    public static void parseConstructAnnotation() {
        Constructor[] constructors = UserAnnotation.class.getConstructors();
        for (Constructor constructor : constructors) {

            boolean hasAnnotation = constructor.isAnnotationPresent(TestA.class);
            if (hasAnnotation) {

                TestA annotation = (TestA) constructor.getAnnotation(TestA.class);
                System.out.println("constructor = " + constructor.getName() + " ; id = "
                        + annotation.id() + " ; description = " + annotation.name() + "; gid= "
                        + annotation.gid());
            }
        }
    }

    public static void main(String[] args) throws ClassNotFoundException {
        parseTypeAnnotation();
        parseMethodAnnotation();
        parseConstructAnnotation();
    }
}
一般通过反射我们能拿到注解里面所有信息。

 下面我就说一下用注解怎么实现观察者模式,代码就不写太多了,
 1.定义注解接口 
 
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE,ElementType.FIELD,ElementType.CONSTRUCTOR})
public @interface AnObser {
    String name();
    int id() default 0;
    String method();
}
这里主要有方法的类型和方法名
2.使用这些注解 
  
public class AnOberser {

    @AnObser(name ="observer",method = "String")
    public void onupdateA(String s) {
        
    }
}
3.向Subject注册
 这里会利用注册的方式对register进来的对象进行解析转换内部,同时保存hashMap中,hashMap的键值为方法的参数类型,value为内部对象,主要包括:注册对象和声明 的观察者回调方法。

4.Subject 通知notify方法:
  主要是根据参数查找内部类,然后利用反射invoke方法进行回调

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值