您的位置:首页 > 编程语言 > Java开发

JAVA技术发展——你不知道的J2SE(四)

2016-05-02 15:30 309 查看
一、Annotation

在java发展到1.8的今天,开发人员对java注解应该都不陌生,无论是SSH框架还是其他java应用,注解的存在为开发人员提供了极大的便利。Java
注解是J2SE5.0中提出的新特性,就相当于一个类,使用这个注解就相当于创建了这个类的实例对象,可以加在包、类、方法、参数、成员变量上,应用非常广泛。

J2SE 5.0中提出了@SuppressWarnings(),@Deprecated@override 三个常用注解,分别用于为类或方法去除编译时警告,过时,覆盖父类方法。在java API的java.lang包下可见这些注解类型和具体使用场景。

二、自定义注解

用了这么多注解,下面介绍如何自己定义注解并应用。

1、定义一个注解

在IDE中创建一个新的Annotation类,形如:

public @interface Annotation1 {

}


2、在其他类中引用该注解,并用反射进行测试,打印注解指向类

@Annotation1
public class AdviseImpl implements Advice {

public static void main(String[] args) {
if(AdviseImpl.class.isAnnotationPresent(Annotation1.class))
{
Annotation1 annotation=(Annotation1)AdviseImpl.class.getAnnotation(Annotation1.class);
System.out.println(annotation);
}
}

测试发现并没有打印出@Annotation1对应的注解类,这就涉及到注解的生命周期。
三、注解生命周期

Java注解有三个生命周期:源文件阶段、class文件阶段、运行时阶段(已经把字节码放入java内存中),默认是class阶段。之所以要批注注解生命周期,是因为源程序在编译成字节码时,或将字节码存入java 内存中,两个阶段均可能将源文件里的注解去掉,规定注解的生命周期处于某个阶段用于确定该注解的保留阶段。
上面例子之所以没有打印注解类,是因为默认生命周期为class,所以运行时并未打印。如果将注解加上@Retention 源注解,这是一个枚举类型,有三个值分别代表注解的三个生命周期:CLASS,SOURCE,RUNTIME;当将注解生命周期设置到运行期时,在执行上面代码可以获取到Annotation1注解的对应类为@it.webservice.mobile.Annotation1()
@Retention(RetentionPolicy.RUNTIME)
public @interface Annotation1 { }
四、注解的作用范围
在注解的应用中,我们知道有使用在类上的注解、方法上的注解、参数、字段的注解,这些就是注解的作用范围,java使用@Target 源注解来设置这一属性,同样@Target 也是枚举类型,.method表示该注解作用于方法之,放到非方法处编译就不会通过;Type
表示可以放到类上,Field -字段;local_Varialble-变量;Parameter-方法的参数。从API中查找ElementType就可以得到这些信息。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})//表示该注解可用于方法、类、字段上
public @interface Annotation1 { }
五、注解的高级应用
为注解设置属性,可能这个名次听起来很陌生,但是相信大家一定使用过这些有着丰富属性的注解。形如:name即为这个无状态注解的属性。

@Stateless(name = "conventionBeanImpl")
有了可配置的属性值大大提高了注解使用的灵活性,减少代码量。那么如何为注解添加属性?

1、为注解添加属性,可设置默认值

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
public @interface Annotation1 {
String color();
String value() default "dfda";
}
2、在使用注解处,为注解传入该属性值,用于初始化注解实例,否则编译报错。注:有default默认值的注解可以不传入。

@Annotation1(color="green")
public class AdviseImpl implements Advice {
public static void main(String[] args) {
if(AdviseImpl.class.isAnnotationPresent(Annotation1.class))
{
Annotation1 annotation=(Annotation1)AdviseImpl.class.getAnnotation(Annotation1.class);
System.out.println(annotation);
System.out.println(annotation.color());
System.out.println(annotation.value());
}
}
分别打印出green和dfda;

3、添加属性值为注解的情况

一般注解的属性值都为基本类型,当遇到属性值为注解时:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
public @interface Annotation1 {
Annotation2 annotationAttr() default @Annotation2(value="dkdkkd"); //属性值为@Annotation2的注解,且Annotation2有个value属性
}
使用该注解时:

@Annotation1(color="green",annotationAttr=@Annotation2("max")) //为Annotation1传入annotationAttr属性,同时传入annotation2的value属性值max
public class AdviseImpl implements Advice {

public static void main(String[] args) {
if(AdviseImpl.class.isAnnotationPresent(Annotation1.class))
{
Annotation1 annotation=(Annotation1)AdviseImpl.class.getAnnotation(Annotation1.class);
}
}
这在EJB3.0中使用非常广泛,项目中多次使用到注解的属性仍是一个注解,通过介绍,现在应该明白原理了。这些特性我们平时都在用,搞明白它的原理,然后自己创建,很容易就能够联想起在项目中的具体应用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: