简介
本文用示例来介绍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)

请先 !