✨
AndroidSummary
  • Introduction
  • 漫品客户端技术总结
    • 小说模块介绍
      • Android不规则布局的实现(万能公式)
      • Android So动态加载原理分析与优雅实现
  • Android总结
  • Android基础
    • Android Activity启动模式
    • Android 之 ThreadLocal简析
    • Android之JNI开发总结
    • 堆和栈的区别
    • java中==,equals,hashcode
    • Java基础数据类型和引用类型的区别
    • Java内部类详解
    • Android 8.0之后Service使用问题
    • 初探RxJava以及结合Retrofit的使用
    • 深入理解--Android Loader
    • 异步线程大师Handler(源码+图+demo+常见问题)
  • [Android AIDL跨进程通信]
    • service的隐式启动和显示启动
    • 如何绕过 Android 8.0 startService 限制
  • Android内存管理
    • Android内存管理(官方概览)
    • Android内存管理(操作系统基础)
    • Android内存管理(内存管理基础)
    • Android内存管理(linux内存管理机制)
    • Android内存管理(Android的内存管理机制简析)
    • Android内存管理(Android对Linux系统的内存管理机制进行的优化)
    • Android内存管理(垃圾回收算法相关)
    • Android内存管理(JVM 、DVM(dalvik) 、ART联系与区别)
    • 命令行提取hprof文件
  • Android安全
    • Android签名攻与防
    • Smalidea+IntelliJ IDEA/Android Studio无源码调试
    • keystore CSR CER PKCS7之间的区别与联系
    • 公钥、私钥、数字签名(签名)、数字证书(证书) 的关系(图文)
    • KeyStore 和 TrustStore区别与联系
    • Android 安全分析和漏洞挖掘|工具集
  • JAVA基础
    • Java 流(Stream)、文件(File)和IO
    • [线程共享和协作]
      • 线程基础、线程之间的共享和协作
      • [synchronized local volatile Threadlocal如何实现线程共享]
        • Synchronized实现原理
        • CAS原理分析
        • Java并发编程:Callable、Future和FutureTask
    • [深入理解Java泛型]
      • 泛型的作用与定义
      • 通配符与嵌套
      • Java泛型擦除及其相关内容
    • [注解深入浅出]
      • 注解是什么,如何理解
      • 自定义注解与元注解
      • 注解的使用场景
    • [并发编程]
      • 线程共享和协作
Powered by GitBook
On this page
  • 注解的使用场景
  • 注解应用实例
  • JUnit
  • ButterKnife
  • Dagger2
  • Retrofit
  • 总结

Was this helpful?

  1. JAVA基础
  2. [注解深入浅出]

注解的使用场景

注解的使用场景

我相信博文讲到这里大家都很熟悉了注解,但是有不少同学肯定会问,注解到底有什么用呢?

对啊注解到底有什么用?

我们不妨将目光放到 Java 官方文档上来。

文章开始的时候,我用标签来类比注解。但标签比喻只是我的手段,而不是目的。为的是让大家在初次学习注解时能够不被那些抽象的新概念搞懵。既然现在,我们已经对注解有所了解,我们不妨再仔细阅读官方最严谨的文档。

注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。

注解有许多用处,主要如下:

  • 提供信息给编译器: 编译器可以利用注解来探测错误和警告信息

  • 编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。

  • 运行时的处理: 某些注解可以在程序运行的时候接受代码的提取

值得注意的是,注解不是代码本身的一部分。

如果难于理解,可以这样看。罗永浩还是罗永浩,不会因为某些人对于他“傻x”的评价而改变,标签只是某些人对于其他事物的评价,但是标签不会改变事物本身,标签只是特定人群的手段。所以,注解同样无法改变代码本身,注解只是某些工具的的工具。

还是回到官方文档的解释上,注解主要针对的是编译器和其它工具软件(SoftWare tool)。

当开发者使用了Annotation 修饰了类、方法、Field 等成员之后,这些 Annotation 不会自己生效,必须由开发者提供相应的代码来提取并处理 Annotation 信息。这些处理提取和处理 Annotation 的代码统称为 APT(Annotation Processing Tool)。

现在,我们可以给自己答案了,注解有什么用?给谁用?给 编译器或者 APT 用的。

如果,你还是没有搞清楚的话,我亲自写一个好了。

亲手自定义注解完成某个目的 我要写一个测试框架,测试程序员的代码有无明显的异常。

—— 程序员 A : 我写了一个类,它的名字叫做 NoBug,因为它所有的方法都没有错误。 —— 我:自信是好事,不过为了防止意外,让我测试一下如何? —— 程序员 A: 怎么测试? —— 我:把你写的代码的方法都加上 @Jiecha 这个注解就好了。 —— 程序员 A: 好的。

/**
NoBug.java
**/
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!");
    }

}

上面的代码,有些方法上面运用了 @Jiecha 注解。

这个注解是我写的测试软件框架中定义的注解。

package ceshi;

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

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

}

然后,我再编写一个测试类 TestTool 就可以测试 NoBug 相应的方法了。

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());

    }

}

测试的结果是:

1234567890
1+1=11
1-1=0
3 x 5=15
chufa has error:

  caused by ArithmeticException

/ by zero

NoBug has  1 error.

提示 NoBug 类中的 chufa() 这个方法有异常,这个异常名称叫做 ArithmeticException,原因是运算过程中进行了除 0 的操作。

所以,NoBug 这个类有 Bug。

这样,通过注解我完成了我自己的目的,那就是对别人的代码进行测试。

所以,再问我注解什么时候用?我只能告诉你,这取决于你想利用它干什么用。

注解应用实例

注解运用的地方太多了,因为我是 Android 开发者,所以我接触到的具体例子有下:

JUnit

JUnit 这个是一个测试框架,典型使用方法如下:

public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

@Test 标记了要进行测试的方法 addition_isCorrect().

ButterKnife

ButterKnife 是 Android 开发中大名鼎鼎的 IOC 框架,它减少了大量重复的代码。

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.tv_test)
    TextView mTv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ButterKnife.bind(this);
    }
}

Dagger2

也是一个很有名的依赖注入框架。

Retrofit

很牛逼的 Http 网络访问框架

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

GitHubService service = retrofit.create(GitHubService.class);

当然,还有许多注解应用的地方,这里不一一列举。

总结

    1. 如果注解难于理解,你就把它类同于标签,标签为了解释事物,注解为了解释代码。

    1. 注解的基本语法,创建如同接口,但是多了个 @ 符号。

    1. 注解的元注解。

    1. 注解的属性。

    1. 注解主要给编译器及工具类型的软件用的。

    1. 注解的提取需要借助于 Java 的反射技术,反射比较慢,所以注解使用时也需要谨慎计较时间成本。

Previous自定义注解与元注解Next[并发编程]

Last updated 4 years ago

Was this helpful?