本文共 5069 字,大约阅读时间需要 16 分钟。
注解可以用于设定或获取对象的属性值,支持单个对象或数组类型。通过注解,可以为属性设定枚举类型的值。
以下是一个使用注解定义枚举类型并实现动态设值的示例:
package org.example.a;import java.lang.annotation.*;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.List;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)@Documented@interface Parent { Color[] value() default {};}@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)@Documented@interface Bottom { String name() default "";}enum Color { RED, @Bottom(name = "浅红色") @Parent({RED}) LIGHT_RED, @Bottom(name = "深红色") @Parent({RED, LIGHT_RED}) DARK_RED; List childrens = new ArrayList(); static List bottoms = new ArrayList(); static { for (Color value : Color.values()) { try { Field field = Color.class.getField(value.name()); if (field.isAnnotationPresent(Bottom.class)) { bottoms.add(value); } Parent parent = field.getAnnotation(Parent.class); if (parent != null) { for (Color color : parent.value()) { color.childrens.add(value); } } } catch (NoSuchFieldException e) { e.printStackTrace(); } } }}public class Demo { public static void main(String[] args) { System.out.println("Color.RED.childrens: " + Color.RED.childrens); System.out.println("Color.LIGHT_RED.childrens: " + Color.LIGHT_RED.childrens); System.out.println("Color.bottoms: " + Color.bottoms); try { Field field = Color.class.getField(Color.LIGHT_RED.name()); if (field.isAnnotationPresent(Bottom.class)) { System.out.println("Color.LIGHT_RED的注解属性名: " + field.getAnnotation(Bottom.class).name()); } } catch (NoSuchFieldException e) { e.printStackTrace(); } }} 执行上述代码后,输出结果如下:
Color.RED.childrens: [LIGHT_RED, DARK_RED]Color.LIGHT_RED.childrens: [DARK_RED]Color.bottoms: [LIGHT_RED, DARK_RED]Color.LIGHT_RED的注解属性名: 浅红色
通过注解和反射机制,可以轻松实现工厂模式,动态地根据注解指定的实现类获取对象实例。这对需要灵活配置服务实现的场景非常有用。
创建一个能够根据注解指定的实现类来获取对应的业务实例。
以下是一个使用注解和反射实现工厂模式的例子:
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 getInstance(Class 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();}// 使用注解指定实现类@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()); } 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.cnclose(proxy)
这个示例展示了如何通过注解和反射机制实现工厂模式。通过注解指定需要使用的实现类,工厂类负责根据注解信息创建相应的实例。这种方法动态、灵活,适合需要根据不同配置或环境选择实现类的场景。
转载地址:http://zytjz.baihongyu.com/