JavaSE学习笔记--Annotation

[size=medium][b]1、annotation是什么?:[/b][/size]
Java注解提供了一套机制,让我们可以对类、方法、参数、包、域及变量等添加标准(即附加某些信息),且可以从源文件、class文件或者以在运行时反射的多种方式被读取。

[size=medium][b]2、常见的annotation:[/b][/size]
a) Override注解表示子类要重写父类的对应方法。
b) Deprecated注解表示方法是不建议被使用的。
c) SuppressWarnings注解表示压制警告。

[size=medium][b]3、自定义注解:[/b][/size]
当注解中的属性名为value时,在对其赋值时可以不指定属性的名称而直接写上属性值即可;除了value以外的其他值都需要使用nam=value这种赋值方式,即明确指定给谁赋值。

[size=small][b]自定义注解需注意的三点:[/b][/size]
a) 当我们使用@interface自定义annotation时,实际上是隐含地继承了java.lang.annotation.Annotation接口。
b) 如果我们定义一个接口,并让该接口继承java.lang.annotation.Annotation接口,那么我们所定义的接口依然是一个接口,而不是注解。
c) Annotation本身是一个接口,而不是注解。

[size=medium][b]4、告知编译程序如何处理@Retention:[/b][/size]
java.lang.annotation.Retention型态可以在你定义Annotation型态时,指示编译程序该如何对待你的自定义的Annotation型态,预设上编译程序会将Annotation信息留在.class文件中,但不会被虚拟机读取,而仅仅用于编译程序或工具程序运行时提供信息。

在使用Retention时,需要提供java.lang.annotation.RetentionPolicy的枚举类型
JDK中源码如下:

package java.lang.annotation;
public enum RetentionPolicy
{
SOURCE, //编译程序处理完Annotation信息后就完成任务,不会被编译到class文件中
CLASS, //编译程序将Annotation存储于class文件中,但不能被VM读取,缺省
RUNTIME //编译程序将Annotation存储于class文件中,可由VM读入,能通过反射读取到
}

RetentionPolicy为SOURCE的例子是@ SuppressWarnings
仅在编译时告知编译程序来抑制警告,所以不必把这个信息存储到.class文件中。

RetentionPolicy为RUNTIME的时机,可以像是你使用java设计一个代码分析工具,你必须让VM能读出Annotation信息,以便在分析程序时使用。搭配反射机制,就可以达到这个目的。

[b]这时,我们来自定义一个注解,并将该注解标注为RUNTIME,然后通过反射来读取其注解的信息。[/b]

代码如下:

//自定义一个注解:

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

@Retention(RetentionPolicy.RUNTIME)//定义为RUNTIME可被反射读取
public @interface MyAnnotation
{
String hello() default "hello eric";
String world();
}

//定义一个类,测试上面的注解:

public class MyTest
{
@MyAnnotation(world = "teng")
public void output()
{
System.out.println("output something");
}
}

//写一个类通过反射API读取MyTest类中注解的信息

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class MyReflection
{
public static void main(String[] args) throws Exception
{
MyTest myTest = new MyTest();

Class<MyTest> c = MyTest.class;

Method method = c.getMethod("output", new Class[]{});

//判断该方法上面是否有MyAnnotation这个注解
if(method.isAnnotationPresent(MyAnnotation.class))
{
method.invoke(myTest, new Object[]{});

MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
String hello = myAnnotation.hello();
String world = myAnnotation.world();

System.out.println(hello);
System.out.println(world);
}

//获取MyTest类中指定方法上的所有注解信息,并将其注解名打印出来
Annotation[] annotations = method.getAnnotations();
for(Annotation annotation : annotations)
{
System.out.println(annotation.annotationType().getName());
}
}
}


程序运行结果:
output something
hello eric
teng
com.annotation.MyAnnotation

[size=medium][b]5、@Target用来声明注解可以,被添加在哪些类型的元素上,如类型、方法和域等。[/b][/size]在定义时要指定java.lang.annotation.ElementType的枚举值之一。
JDK中ElementType源码如下:

package java.lang.annotation
public enum ElementType
{
Type, //适用class,interface,enum
FIELD, //适用field
METHOD, //适用method
PARAMETER, //适用method里的parameter
CONSTUCTOR, //适用constructor
LOCAL_VARIABLE, //适用局部变量
ANNOTATION_TYPE, //适用annotation型态
PACKAGE //适用package
}


还是写一段代码来演示:
//自定义一个注解MyTarget:

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

@Target(ElementType.METHOD)//表示该注解只能修饰方法
public @interface MyTarget
{
String hello();
}


//写个类测试该注解:

public class MyTargetTest
{
@MyTarget(hello="eric")//如果将该注解放在类之上,就会报错
public void doSomething()
{
System.out.println("mytarget test");
}
}


[size=medium][b]6、子类是否继承父类@Inherited?[/b][/size]
默认上父类中的Annotation并不会被子类继承。若想让子类继承父类的Annotation,可以在定义Annotation时加上java.lang.annotation.Inherited型态的Annotation。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值