Java之Annotation注解

Java语言是纯面向对象的。

一、注解简介

1.引入时间:JDK1.5版本引入注解。

2.什么是注解?

注解,也叫做元数据。一种代码级别的说明。它与类,接口,枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数的前面,用来对这些元素进行说明,注释。这些说明被存储在Annotation注解的“name=value”结构中。

3.注解的作用

编写文档:通过代码里标识的元数据生成文档。

代码分析:通过代码里标识的原数据对代码进行分析。

编译检查:通过代码里标识的原数据让编译器能实现基本的编译检查。

4.注解的分类

4.1 JDK自带的注解

@override:表示子类覆写父类的方法。

@Deprecated:表示该方法已被弃用。

@SuppressWarnings:表示忽略指定警告,eg:@SuppressWarnings("Deprecation");

说明:(1)这三种注解都是在编译时注解,在源码和.class文件中都存在。

(2)注解的继承只能作用在类上,方法上的注解不会被继承,Interface中的所有注解不会被继承。

还有四种元注解

@Target  注解作用域,表示该注解可以用于一个类中的那些属性及方法上,,如果该作用域有多个可以用英文逗号分隔。

@Retention  表示该注解的生命周期。

@Documented  表示生成javadoc时会包含注解。

@Inherited   标识性的元注解,表示当前注解可以由子注解继承。

4.2 第三方注解

4.3 自定义注解

语法:

@<注解名>(<成员名1>=<成员值1>,<成员名2=成员值2>,...)

5.注解的生命周期

每个Annotation都有自己的运行范围,而这些范围在一个枚举类(java.lang.annotation.RetentionPolicy)中定义:

SOURCE:在源代码中出现的注解,编译时丢弃。

CLASS:编译时还在,运行时丢弃。

RUNTIME:运行时仍然存在,可以通过反射获取。

二、反射与Annotation

1.反射取得注解信息

public Annotation[] getAnnotations();   取得全部Annotation
public T getAnnotation(Class annotationClass);   取得指定的Annotation

1.1 取得在类上定义的Annotation

package com.com.company.reflection;

import java.io.Serializable;
import java.lang.annotation.Annotation;
@SuppressWarnings("serial")//告诉编译器忽略“serial”警告信息。
@Deprecated//表明A类被禁用,在使用时会出现A划斜线。
class A implements Serializable {
    @Override
    public String toString(){
        return "覆写";
    }

}
public class TestAnnotation {
    public static void main(String[] args) {
        Annotation[] annotations=A.class.getAnnotations();
        for(Annotation annotation:annotations){
            System.out.print(annotation+" ");
        }
        Annotation annotation = A.class.getAnnotation(java.lang.annotation.Annotation.class);
        System.out.println(annotation);
    }
}

因为不同的Annotation有自己的保存范围,它们的返回也不同。因此此时只返回了一个Annotation。

1.2 在方法上使用Annotation

package com.com.company.reflection;

import java.io.Serializable;
import java.lang.annotation.Annotation;
@SuppressWarnings("serial")
@Deprecated
class A implements Serializable {
    @Deprecated
    @Override
    public String toString(){
        return super.toString();
    }

}
public class TestAnnotation {
    public static void main(String[] args) {
        Annotation[] annotations=new Annotation[0];
        try {
            annotations=A.class.getMethod("toString").getAnnotations();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        for(Annotation annotation:annotations){
            System.out.print(annotation+" ");
        }
      
    }
}

结果:

2.自定义注解

package com.com.company.reflection;


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

//自定义注解
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
    public String name() default "张三";//设置默认值
    public int age() default 18;
}

@MyAnnotation(name="李四",age=38)//可以在注解后面修改
class A  {
    @Deprecated
    @Override
    public String toString(){
        return super.toString();
    }

}
public class TestAnnotation {
    public static void main(String[] args) {
       MyAnnotation myAnnotation=A.class.getAnnotation(MyAnnotation.class);
       System.out.println("姓名:"+myAnnotation.name());
       System.out.println("年龄:"+myAnnotation.age());
    }
}

结果:

三、注解与工厂设计模式

前面介绍的工厂有一个用于不同产品实现不同方法的接口,产品类和工厂类。在工厂类中生产产品(实例化对象),接口中定义方法,不同的产品类根据自己的需要实现接口中的方法。在反射(一)中已经介绍过传统的工厂设计模式的缺点是一旦增加商品,在工厂类中实例化对象的方法代码就要进行改动。我们通过反射机制避免了这一弊端,通过类的Class对象的newInstance()获取实例化对象,避免了大量代码的改动。而通过对注解的认识,我们可以通过在注解中设置目标。在工厂类上面可以对想要的目标进行修改,从而获取实例化对象。

package com.com.company.reflection;


import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
    public Class<?> target();
}
//定义一个接口,产品都要实现这个接口。
interface IFastFood{
    public void eat();
}

class Pizza implements IFastFood{

    @Override
    public void eat() {
        System.out.println("吃披萨");
    }
}
class Hamburger implements IFastFood{

    @Override
    public void eat() {
        System.out.println("吃汉堡包");
    }
}

//定义一个工厂生产这种产品
@MyAnnotation(target=Hamburger.class)//设置要生产的产品
class Factory{
    public static IFastFood getInstance() throws IllegalAccessException, InstantiationException {
        MyAnnotation a=Factory.class.getAnnotation(MyAnnotation.class);
        return (IFastFood)a.target().newInstance();
    }
}
public class TestAnnotation {
    public static void main(String[] args) {
        try {
           IFastFood fastFood= (IFastFood) Factory.getInstance();
           fastFood.eat();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
}

结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值