反射之注解快速了解

目录

反射获取Annotation

可以通过反射获取注解信息。

在这里插入图片描述
常用方法:

方法说明
public A getAnnotation(Class annotationClass)获取指定类型的Annotation
public Annotation[] getAnnotations()获取全部的Annotation
public A[] getAnnotationsByType(Class annotationClass)得到拥有指定类型的Annotation
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)判断是否存在指定的Annotation注解

示例:

public class TestAnnotation {
    public static void main(String[] args) throws NoSuchMethodException {
        String value = "com.tx.test.annotation.MessageImpl";
        IMessage message = Factory.getInstance(value);
        message.send("www.baidu.com");
        System.out.println("------------------------------------");
        Annotation[] annotations = IMessage.class.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        System.out.println("------------------------------------");
        Annotation[] annotationsTest = MessageImpl.class.getAnnotations();
        for (Annotation annotation : annotationsTest) {
            System.out.println(annotation);
        }
        System.out.println("------------------------------------");
        //方法获取不到@Override注解
        Method method = MessageImpl.class.getDeclaredMethod("send", String.class);
        Annotation[] annotationsT = method.getAnnotations();
        for (Annotation annotation : annotationsT) {
            System.out.println(annotation);
        }
    }
}

@FunctionalInterface
@Deprecated(since = "3.0")
interface IMessage {
    /**
     * 输出数据
     *
     * @param msg 传递的数据
     */
    void send(String msg);
}

@Deprecated(since = "1.7")
class MessageImpl implements IMessage {

    @Override
    @Deprecated(since = "1.5")
    public void send(String msg) {
        System.out.println(msg);
    }
}

class Factory {
    private Factory() {
    }

    @SuppressWarnings("unchecked")
    public static <T> T getInstance(String classValue) {
        Object object = null;
        try {
            Class<?> clazz = Class.forName(classValue);
            object = clazz.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            return null;
        }
        return (T) object;
    }
}

结果:

www.baidu.com
------------------------------------
@java.lang.FunctionalInterface()
@java.lang.Deprecated(forRemoval=false, since="3.0")
------------------------------------
@java.lang.Deprecated(forRemoval=false, since="1.7")
------------------------------------
@java.lang.Deprecated(forRemoval=false, since="1.5")

自定义Annotation

可以自己生成一个注解进行操作。

@Retention:

1、SOURCE:在源代码编写过程中生效。

2、CLASS:再类定义时生效。

3、RUNTIME:在类执行的时候生效。

@Target:

1、ANNOTATION_TYPE:只能够出现在注解定义的操作上。

2、METHOD:只能出现在方法上。

3、FIELD:只能出现在成员属性上。

4、TYPE:只能出现在类结构上。

5、PARAMETER:只能狗出现在参数上。

示例:

public class AnnotationTest {
    public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException {
        Class<?> clazz = Message.class;
        Method method = clazz.getDeclaredMethod("send");
        Field field = clazz.getDeclaredField("name");
        Annotation[] methodAnnotations = method.getAnnotations();
        Annotation[] fieldAnnotations = field.getAnnotations();
        for (Object annotation : fieldAnnotations) {
            System.out.println("FIELD:"+annotation);
        }
        System.out.println("--------------------------------------");
        for (Object annotation : methodAnnotations) {
            System.out.println("METHOD:"+annotation);
        }
    }
}
//设置注解可以用到得范围(成员属性和方法)
@Target({ElementType.FIELD, ElementType.METHOD})
//设置运行范围
@Retention(RetentionPolicy.RUNTIME)
@interface Action {
    String title() default "Hello World!!!";    //设置默认值

    String value();	
}

class Message {
    @Action("tan")	//value可以直接赋值
    private String name;

    @Action("tan")
    public void send() {

    }
}

结果:

FIELD:@com.tx.test.annotation.Action(title="Hello World!!!", value="tan")
--------------------------------------
METHOD:@com.tx.test.annotation.Action(title="Hello World!!!", value="tan")

Annotation和动态工厂模式

使用注解可以根据注解的值进行实例化操作,完全解耦。

在这里插入图片描述

package com.tx.test.factoryannotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

public class TestFactoryAnnotation {
    public static void main(String[] args) throws Exception{
        new Message().send("www.baidu.com");
    }
}

@Target(ElementType.TYPE)   //在类中都有效
@Retention(RetentionPolicy.RUNTIME)
@interface Action {
    String value();
}

@Target(ElementType.CONSTRUCTOR)    //在构造中有效
@Retention(RetentionPolicy.RUNTIME)
@interface ConstructorValue {
    String value();
}

interface IMessage extends AutoCloseable {
    /**
     * 建立通讯连接
     *
     * @return 返回boolean值
     */
    boolean build();
}

class InternetMessage implements IMessage {

    @Override
    public boolean build() {
        System.out.println("【InternetMessage】互联网通讯连接。。。");
        return true;
    }

    @Override
    public void close() throws Exception {
        System.out.println("【InternetMessage】互联网通讯关闭。。。");
    }
}

class RadioMessage implements IMessage {

    @Override
    public boolean build() {
        System.out.println("【RadioMessage】无线通讯连接。。。");
        return true;
    }

    @Override
    public void close() throws Exception {
        System.out.println("【InternetMessage】无线电通讯关闭。。。");
    }
}

class Factory {
    private Factory() {
    }
    @SuppressWarnings("unchecked cast")
    public static <T> T getInstance(String kindName) {
        try {
            return (T) Class.forName(kindName).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            return null;
        }
    }
}

@Action("com.tx.test.factoryannotation.RadioMessage")
class Message{
    private IMessage message;
    @ConstructorValue("com.tx.test.factoryannotation.Factory")
    public Message(){
        try{
           String actionValue = this.getClass().getAnnotation(Action.class).value();
           String constructorValue = this.getClass().getConstructor().getAnnotation(ConstructorValue.class).value();
           this.message = (IMessage) Class.forName(constructorValue).getMethod("getInstance",String.class).invoke(null,actionValue);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void send(String msg) throws Exception {
        if(this.message.build()){
            System.out.println("【消息发送】"+msg);
            this.message.close();
        }
    }
}

结果:

【RadioMessage】无线通讯连接。。。
【消息发送】www.baidu.com
【InternetMessage】无线电通讯关闭。。。
    

只需要将Action的位置换成另一个子类,就可以直接调用累一个类的build和close的方法。

@Action("com.tx.test.factoryannotation.InternetMessage")
//结果
【InternetMessage】互联网通讯连接。。。
【消息发送】www.baidu.com
【InternetMessage】互联网通讯关闭。。。    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值