所有分类
  • 所有分类
  • 未分类

Java之注解-使用/实例

简介

本文用示例来介绍Java中的注解的应用。包括:注解设值/取值、Annotation+反射 实现工厂模式。

注解设值/取值

简介

属性可以是单个对象,也可以是数组。

可以把注解的属性设置为枚举类型;

需求

有红色、浅红色、深红色,三种颜色。其中:

  1. 红色是浅红色和深红色的父颜色;
  2. 浅红色是深红色的父颜色
  3. 深红色是最底层的颜色(不能有子颜色)。

要求使用注解和枚举,将上边的结构表示出来。并写一个测试类,输出红色的所有直接子颜色(应该是浅红色和深红色),输出浅红色的所有子颜色(应该是深红色),输出所有最底层的颜色(应该是深红色)。

代码

注解类

package com.example.test;

import java.lang.annotation.*;

/**
 * 指定颜色的父颜色(所属颜色)
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
@interface Parent {
    Color[] value() default {};
}
package com.example.test;

import java.lang.annotation.*;

/**
 * 表示是最底层的(即:没有子层)
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
@interface Bottom {
    String name() default "";
}

枚举类

package com.example.test;
 
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
 
enum MyColor {
    RED,

    @Parent({RED})
    LIGHT_RED,
 
    @Bottom(name = "深红色")
    @Parent({RED, LIGHT_RED})
    DARK_RED;

    static List<MyColor> bottoms = new ArrayList<>();

    List<MyColor> children = new ArrayList<>();

    static {
        for (MyColor value : MyColor.values()) {
            try {
                Field field = MyColor.class.getField(value.name());
                if (field.isAnnotationPresent(Bottom.class)) {
                    bottoms.add(value);
                }

                Parent parent = field.getAnnotation(Parent.class);
                if (parent != null) {
                    for (MyColor myColor : parent.value()) {
                        myColor.children.add(value);
                    }
                }
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
    }
}

测试类 

package com.example.test;
 
import java.lang.reflect.Field;

public class Demo {
    public static void main(String[] args) {
        System.out.println("MyColor.RED.children:         " + MyColor.RED.children);
        System.out.println("MyColor.LIGHT_RED.children:   " + MyColor.LIGHT_RED.children);
        System.out.println("MyColor.bottoms:              " + MyColor.bottoms);
 
        try {
            Field field = MyColor.class.getField(MyColor.DARK_RED.name());
            if (field.isAnnotationPresent(Bottom.class)) {
                System.out.println("MyColor.DARK_RED的注解属性名: " +
                        field.getAnnotation(Bottom.class).name());
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

测试

MyColor.RED.children:         [LIGHT_RED, DARK_RED]
MyColor.LIGHT_RED.children:   [DARK_RED]
MyColor.bottoms:              [DARK_RED]
MyColor.DARK_RED的注解属性名: 深红色

Annotation+反射 实现工厂模式

简介

需求:有个短信发送功能,有两个实现类,通过注解来指定使用哪种实现。

代码 

package org.example.a;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//业务接口
interface IMessage{
    public void send(String msg);
}

//业务接口实现子类
class IMessageImpl1 implements IMessage{
    @Override
    public void send(String msg) {
        System.out.println("send(IMessageImpl1): " + msg);
    }
}

//业务接口实现子类
class IMessageImpl2 implements IMessage{
    @Override
    public void send(String msg) {
        System.out.println("send(IMessageImpl2): " + msg);
    }
}

class Factory{
    private Factory() {}
    public static <T> T getInstance(Class<T> clazz) {
        try {    //利用反射获取实例化对象
            return (T) new MessageProxy().bind(clazz.getDeclaredConstructor().newInstance());
        } catch (Exception e) {
            return null;
        }
    }
}

class MessageProxy implements InvocationHandler {
    private Object target;
    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }
    public boolean connect() {
        System.out.println("connect(proxy)");
        return true;
    }
    public void close() {
        System.out.println("close(proxy)");
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            if(this.connect()) {
                return method.invoke(this.target, args);//代理调用
            }else {
                throw new Exception("cannont send");
            }
        } finally {
            this.close();
        }
    }
}

@Target({ElementType.TYPE, ElementType.METHOD}) //只能用在类和方法上
@Retention(RetentionPolicy.RUNTIME)
@interface UseMessage{
    //定义要使用的类型
    public Class<?> clazz();
}

//Annotation定义使用类。红色部分可以修改为其他实现类,实现调用不同类输出。
@UseMessage(clazz = IMessageImpl1.class)
class MessageService{
    private IMessage message;        //定义业务处理
    public MessageService() {
        UseMessage use = MessageService.class.getAnnotation(UseMessage.class);
        this.message = (IMessage) Factory.getInstance(use.clazz());    //通过Annotation获取
    }
    public void send(String msg) {
        this.message.send(msg);
    }
}

public class Demo {
    public static void main(String[] args) {
        MessageService messageService = new MessageService();
        messageService.send("www.sina.com.cn");
    }
}

输出结果

connect(proxy)
send(IMessageImpl1): www.sina.com.cn
close(proxy)
0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录