简介
本文用示例来介绍Java中的注解的应用。包括:注解设值/取值、Annotation+反射 实现工厂模式。
注解设值/取值
简介
属性可以是单个对象,也可以是数组。
可以把注解的属性设置为枚举类型;
需求
有红色、浅红色、深红色,三种颜色。其中:
- 红色是浅红色和深红色的父颜色;
- 浅红色是深红色的父颜色
- 深红色是最底层的颜色(不能有子颜色)。
要求使用注解和枚举,将上边的结构表示出来。并写一个测试类,输出红色的所有直接子颜色(应该是浅红色和深红色),输出浅红色的所有子颜色(应该是深红色),输出所有最底层的颜色(应该是深红色)。
代码
注解类
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)
请先
!