Java中的注解

最简单的理解,注解就和标签一样,是对抽象事物的解释;

这是在看http://blog.csdn.net/briblue/article/details/73824058

博客时最先总结的一句话但都看完之后感觉注解是一个标签但他也是对一个方法或类的声明,比如说这个类是我写的,我可以给他贴一个标签,上面贴上本人的大名

我来用我当时看博客的疑问思路来解释一下,首先我们是不是要问既然解释和理解都这么复杂,那我们用实际例子来说明注解到底是干什么的,然后来一行一行的深入了解一下。

好了废话到这里先来我的小例子(这也是上面这篇博客里的小例子,先说明一下,防止被人锤):

我们先来写一个自己的注解(带着疑问看完这篇博客再说):

@Retention(RetentionPolicy.RUNTIME)// 这个是元注解之一,这一行就是注解说明这个注解在运行时还有效(这行注释很重要)
public @interface 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);}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> ziwojieshao(){
    System.</span><span style="color: rgba(0, 0, 255, 1)">out</span>.println(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">我写的程序没有 bug!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
}

}

可以看到我们的方法都加上了我们的注解

那么我们就用一下我们的注解,

如果一点都看不懂下面的代码就先跳到代码下面的文字部分,看完再回来看代码

public class MainActivity extends AppCompatActivity {
    TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv=findViewById(R.id.tv);
        NoBug noBug = new NoBug();//new 出我们写的检查 bug 类的对象
        Class aClass = noBug.getClass();// 获取到 class 对象
        Method[] dm = aClass.getDeclaredMethods();// 将 NoBug 类中的所有方法都存在 dm 数组中
        StringBuilder log = new StringBuilder();// 创建一个StringBuilder来拼接我们的错误报告
        // 记录异常的次数
        int errornum = 0;// 定义一个 int 类型的数值来记录我们报了几次错
        for (Method m: dm) {// 循环遍历我们的数组(就是我们定义的类里面的方法)
            // 只有被 @Jiecha 标注过的方法才进行测试
            if ( m.isAnnotationPresent( Jiecha.class )) {// 如果这个方法上有我们的注解我们就进行测试
                try {
                    m.setAccessible(true);// 打开获取私有方法的权限
                   m.invoke(noBug, null);// 执行这个 m 方法
            } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO Auto-generated catch block
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">e.printStackTrace();</span>
                errornum++<span style="color: rgba(0, 0, 0, 1)">;//报错数加一
                log.append(m.getName());//获取当前报错方法的名字
                log.append(</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
                log.append(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">has error:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
                log.append(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\n\r  caused by </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">记录测试过程中,发生的异常的名称</span>

log.append(e.getCause().getClass().getSimpleName());
log.append(
"\n\r");
//记录测试过程中,发生的异常的具体信息
log.append(e.getCause().getMessage());
log.append(
"\n\r");
}
}
}
log.append(aClass.getSimpleName());
log.append(
" has ");
log.append(errornum);
log.append(
" error.");
// 生成测试报告
tv.setText(log.toString());
}
}

首先,我们会发现里面使用了 Java 的反射,这是为什么,细心的你会看到我粘贴的代码里的第一行注释,我们的注解是到运行时还有效的,而我们这个代码的主要功能是检查我们报的错

而运行时的错误,当然是在运行时,而我们的 Java 文件在编译后会变成 Class 文件才能在 JVM 中运行(如果你不知道 JVM 那就自己问一下度娘吧),所有我们需要用反射才能获取到我们

在运行时报的错,这里先给大家把反射中的注释都加上,可以方便大家看代码。

 

这就是注解的一个使用,如果还是看不懂,那么我们最简单的一个例子,我们在用到过时的方法时这个方法上面会被画上一条线

这条线怎么来的呢,就是这个方法被加上了@Deprecated 这个注解,自己可以写着调用一下,这个注解就是用来警告我们,这个方法已经过时了;

这个时候我们再来说其实注解就和其实同 classs 和 interface 一样,注解也属于一种类型。它是在 Java SE 5.0 版本中开始引入的概念。

那么我们怎么定义一个注解的:

和写 abstract class 一样我们这里要写 @interface

public @interface MyZj {String name();
    int age();}

而里面就是要写注解的属性也叫做成员变量。注解只有成员变量,没有方法。注解的成员变量在注解的定义中以“无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。就是上面的这种形态;

我们在使用的时候

@MyZj(name="***",age = 1)
public class Myclass {
}

这就是最简单的使用然后是元注解在上面的那个博客里非常详细,这里就不再重复写了,和 Java 预置的注解比如我们的重写@Override

官方的注解的说法:

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

注解有许多用处,主要如下:
- 提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
- 编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html 文档或者做其它相应处理。
- 运行时的处理: 某些注解可以在程序运行的时候接受代码的提取

这就是注解最初步的了解然后可以多看看上面的这个帖子,慢慢就会了解注解的;