【2016-03-01】Java注解

常常在代码中看到注解,经常使用的有@Override、@Deprecated、Spring注解。html

@Override代码以下:java

package java.lang;
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

Override里面很干净,什么都没有,可是外面有。编程

涉及到了两个元注解:api

@Target :顾名思义,说明@Override能够用来注解方法oracle

@Retention:定义该注解的生命周期,默认为RetentionPolicy.CLASS。jvm

类型 使用场景 常见例子
RetentionPolicy.SOURCE 在编译阶段丢弃。这些注解在编译结束以后就再也不有任何意义,因此它们不会写入字节码。 @Override, @SuppressWarnings都属于这类注解。
RetentionPolicy.CLASS 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
RetentionPolicy.RUNTIME 始终不会丢弃,运行期也保留该注解,所以可使用反射机制读取该注解的信息。 咱们自定义的注解一般使用这种方式。


查api doc,看到还有另外两种元注解:ide

@Documented:注解是否将包含在JavaDoc中函数

@Inherited:是否容许子类继承该注解spa

另外,还发现了一个Annotation接口.net

package java.lang.annotation;

public interface Annotation {
boolean equals(Object obj);
int hashCode();
    Class<? extends Annotation> annotationType();
}

此接口功能以下(虽然有点绕,可是说的仍是挺清楚地):

一、任何注解都继承了此接口;

二、经过 xxInterface extends Annotation方式继承的不声明注解;

三、此接口本身没有声明注解。

这个知乎问题知道,注解反编译以后实际上继承了Annotation。


言归正传,看过了@Override的代码,会产生2个疑问:

一、@Override的功能(检查在父类中有一个相同签名的函数)是谁来完成的?

二、如何自定义一个注解?

咱们先说第二个问题~


1、如何自定义一个Annotation?

简单如@Retention,发现Retention能够本身注解本身,这不算犯规。

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

自定义代码(引自refer2连接):

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
    int count() default 1;    // 默认是public,default不是必须的,方法必须有返回值;
}

@TestAnnotation(count = 0x7fffffff)
public class TestMain {
    public static void main(String[] args) throws InterruptedException, NoSuchFieldException, IllegalAccessException, IOException {
        TestAnnotation annotation = TestMain.class.getAnnotation(TestAnnotation.class);
        System.out.println(annotation.count());
        System.in.read();
    }
}

refer3里有个Filed的例子,这个博客被转的还蛮多的。


2、@Override的功能是谁来完成的?

如今的java IDE都是自动编译的,编译的时候就能够检查是否正确的Override了父类的方法了~


PS: JVM是如何选择@Override的方法的?

看了一些博客以后,大概明白了。因为继承的存在,变量具备“静态类型”和“实际类型”,静态类型在编译器肯定,实际类型在运行期肯定,执行的时候调用实际类型的Override的方法便可。

Override和Overload的底层实现叫作“分派”(原谅本身第一次见到这个词)。发现Override是jvm的一个叫“动态分派”的过程完成的,与之相对的静态分派是重载(Overload)。除此以外还有多分派、单分派这对术语。


3、相关问题

一、Spring中使用注解注册Bean;

二、XML vs. Annotation


refer:

一、Java中的注解是如何工做的?

二、java注解是怎么实现的?

三、java 注解的基本原理和编程实现

相关文章
相关标签/搜索