美文网首页
注解基本应用

注解基本应用

作者: 极客123 | 来源:发表于2018-09-20 15:17 被阅读0次

注解:

注解目前非常的流行,很多主流框架都支持注解,而且自己编写代码的时候也会尽量的去用注解,既方便,也让代码更加简洁。

注解杂谈:


Annontation是Java5开始引入的新特征,中文名称叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用。Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。


你常见到的这个东东,还记得吗?

  @Override
    public String toString() {
        return "Test{}";
    }

@Override 就是我们接下来要说的注解了,这个注解用来标记子类重写的父类中的方法,如果父类中没有该方法,则编译器就会报错提示开发者

常见的元注解

@Documented –注解是否将包含在JavaDoc中
@Retention –什么时候使用该注解
@Target? –注解用于什么地方
@Inherited – 是否允许子类继承该注解

注解-简而言之:解释某个方法或者字段或者类,予以标记,让代码更易阅读。


使用Annotation之前(甚至在使用之后),XML被广泛的应用于描述元数据。不知何时开始一些应用开发人员和架构师发现XML的维护越来越糟糕了。他们希望使用一些和代码紧耦合的东西,而不是像XML那样和代码是松耦合的(在某些情况下甚至是完全分离的)代码描述。
假如你想为应用设置很多的常量或参数,这种情况下,XML是一个很好的选择,因为它不会同特定的代码相连。如果你想把某个方法声明为服务,那么使用Annotation会更好一些,因为这种情况下需要注解和方法紧密耦合起来,开发人员也必须认识到这点
另一个很重要的因素是Annotation定义了一种标准的描述元数据的方式。在这之前,开发人员通常使用他们自己的方式定义元数据。例如,使用标记interfaces,注释,transient关键字等等。每个程序员按照自己的方式定义元数据,而不像Annotation这种标准的方式。
目前,许多框架将XML和Annotation两种方式结合使用,平衡两者之间的利弊。
简单来说:本来可能需要很多配置文件,需要很多逻辑才能实现的内容,就可以使用一个或者多个注解来替代,这样就使得编程更加简洁,代码更加清晰。


注解的用处:
1、生成文档。这是最常见的,也是java 最早提供的注解。常用的有@param @return 等
2、跟踪代码依赖性,实现替代配置文件功能。比如Dagger 2依赖注入,未来java开发,将大量注解配置,具有很大用处;
3、在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。
注解的原理:
  注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy1。通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。


简单用下注解,随机献上老栈的DEMO

创建自定义注解类:

import com.sun.istack.internal.Interned;
import java.lang.annotation.*;
//该注解使用范围在方法上
@Target(ElementType.METHOD)
//该注解用来指定编译的时期
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
    //配置几个解释的字段,如果该字段有默认值,可以使用default指定
    public int id ();
    public String description() default "test";
}

注解:根据需要设置字段,有时候也不需要设置,仅仅起到标记作用,类似于空接口

接下来:创建一个自定义的类

public class PasswordUtils {
     @UseCase(id = 47, description ="密码描述")
     public boolean validatePassword(String password) {
         return (password.matches("\\w*\\d\\w*"));
     }
     @UseCase(id = 50)
     public String encryptPassword(String password) {
         return new StringBuilder(password).reverse().toString();
     }
}

这样在测试类中,对于进行注解标记的字段,就可以通过java 反射,获取到二进制文件,从而获取在方法、字段、类、或者接口顶部的注解,而根据自定义注解的内容,便可以根据数据的含义进行数据操作,简化代码,或者根据某个注解某个特殊的值来进行业务处理,很多框架也多有类似设计。

测试类:

    public static void main(String[] args) {
        List<Integer> useCases = new ArrayList<Integer>();
        Collections.addAll(useCases, 47, 48, 49, 50);
        trackUseCases(useCases, PasswordUtils.class);
    }

    public static void trackUseCases(List<Integer> useCases, Class<?> cl) {
        for (Method m : cl.getDeclaredMethods()) {
            UseCase uc = m.getAnnotation(UseCase.class);
            if (uc != null) {
                System.out.println("Found Use Case:" + uc.id() + " "
                        + uc.description());
                useCases.remove(new Integer(uc.id()));
            }
        }
        for (int i : useCases) {
            System.out.println("Warning: Missing use case-" + i);
        }
    }

注解学习要点:

1.注解的元注解。
2.注解的属性。
3.注解主要给编译器及工具类型的软件用的。
4.注解的提取需要借助于 Java 的反射技术,反射比较慢,所以注解使用时也需要谨慎计较时间成本。


待续。。。

追加一个补充例子: 对他人写的代码检测,注解样例:

注解样例

package ceshi;

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

@Retention(RetentionPolicy.RUNTIME)
public @interface Jiecha {

}

*** 检测类***

package ceshi;
import ceshi.Jiecha;


public class NoBug {

    @Jiecha
    public void suanShu(){
        System.out.println("1234567890");
    }
    @Jiecha
    public void jiafa(){
        System.out.println("1+1="+1+1);
    }
    @Jiecha
    public void jiefa(){
        System.out.println("1-1="+(1-1));
    }
    @Jiecha
    public void chengfa(){
        System.out.println("3 x 5="+ 3*5);
    }
    @Jiecha
    public void chufa(){
        System.out.println("6 / 0="+ 6 / 0);
    }

    public void ziwojieshao(){
        System.out.println("我写的程序没有 bug!");
    }

}
检测执行:
package ceshi;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;



public class TestTool {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        NoBug testobj = new NoBug();

        Class clazz = testobj.getClass();

        Method[] method = clazz.getDeclaredMethods();
        //用来记录测试产生的 log 信息
        StringBuilder log = new StringBuilder();
        // 记录异常的次数
        int errornum = 0;

        for ( Method m: method ) {
            // 只有被 @Jiecha 标注过的方法才进行测试
            if ( m.isAnnotationPresent( Jiecha.class )) {
                try {
                    m.setAccessible(true);
                    m.invoke(testobj, null);

                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    //e.printStackTrace();
                    errornum++;
                    log.append(m.getName());
                    log.append(" ");
                    log.append("has error:");
                    log.append("\n\r  caused by ");
                    //记录测试过程中,发生的异常的名称
                    log.append(e.getCause().getClass().getSimpleName());
                    log.append("\n\r");
                    //记录测试过程中,发生的异常的具体信息
                    log.append(e.getCause().getMessage());
                    log.append("\n\r");
                } 
            }
        }


        log.append(clazz.getSimpleName());
        log.append(" has  ");
        log.append(errornum);
        log.append(" error.");

        // 生成测试报告
        System.out.println(log.toString());

    }

}

结合反射, 注解效力。


如果大家有时间也可以研究下Hibernate的框架,通过注解是如何生成sql语句的呢? 日后有时间会更新该Demo,希望大家支持关注,过几天手写Hibernate注解Demo。。。

相关文章

  • 注解基本应用

    注解: 注解目前非常的流行,很多主流框架都支持注解,而且自己编写代码的时候也会尽量的去用注解,既方便,也让代码更加...

  • Java的注解-元注解

    元注解 元注解是一种基本注解,它能够应用到其它的注解上面。元标签有: @Retention、@Documented...

  • Kotlin注解(2)自定义注解

    声明注解案例:使用元注解注解目标声明案例:读取运行时注解信息   与基本注解不同,在一般的应用开发中不会直接使用元...

  • Kotlin 注解与反射摘要

    声明并应用注解 注解只能拥有如下类型的参数:基本数据类型、字符串、枚举、类引用、其他的注解类,以及前面这些类型的数...

  • SpringMVC的@ResponseBody注解说明

    @ResponseBody 注解与 @RequestBody 注解类似。 @ResponseBody 注解可被应用...

  • SpringBoot集成EhCache

    目标 网上的集成方案基本都是使用缓存注解来使用ehcache,但在实际应用中很不灵活。本文介绍了非注解方式无配置文...

  • Java 初识注解

    一、注解的基本概念 Annotation(注解,也叫元数据)是一种应用于类、方法、参数、变量、构造器及包声明中的特...

  • Spring注解大全

    Spring使用的注解大全和解释 注解解释@Controller组合注解(组合了@Component注解),应用在...

  • Kotlin注解

    定义注解 注解使用 Kotlin的元注解 @Target:定义注解能够应用于哪些目标对象 (CLASS,FUNCT...

  • SpringBoot2.0--SpringBootApplica

    1.@SpringBootApplication 应用启动注解,标记应用入口,当然也可以不使用这个注解,而拆分为多...

网友评论

      本文标题:注解基本应用

      本文链接:https://www.haomeiwen.com/subject/opbgnftx.html