简介
本文用示例来介绍Java中的注解的应用。包括:注解设值/取值、Annotation+反射 实现工厂模式。
注解设值/取值
简介
属性可以是单个对象,也可以是数组
可以设值属性为枚举类型;
实例
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<Color> childrens = new ArrayList<>();
static List<Color> 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的注解属性名: 浅红色
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)