关闭

浅谈java反射

标签: java注解
132人阅读 评论(0) 收藏 举报

一、注解的作用:

             1、生成文档。这是最常见的,也是java 最早提供的注解。常用的有@see @param @return 等

             2、跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。以后java的程序开发,最多的也将实现注解配置,具有很大用处;

             3、在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。

   

作用分类:
①编写文档:通过代码里标识的元数据生成文档【生成文档doc文档】
② 代码分析:通过代码里标识的元数据对代码进行分析【使用反射】
③编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】

二、元注解:表示的是注解的注解

三、Java中提供了四种元注解,专门负责注解其他的注解,分别如下

     @Retention元注解,表示需要在什么级别保存该注释信息(生命周期)。可选的RetentionPoicy参数包括:
         RetentionPolicy.SOURCE: 停留在java源文件,编译器被丢掉
         RetentionPolicy.CLASS:停留在class文件中,但会被VM丢弃(默认)
         RetentionPolicy.RUNTIME:内存中的字节码,VM将在运行时也保留注解,因此可以通过反射机制读取注解的信息

    @Target元注解,默认值为任何元素,表示该注解用于什么地方。可用的ElementType参数包括
        ElementType.CONSTRUCTOR: 构造器声明
        ElementType.FIELD: 成员变量、对象、属性(包括enum实例)
        ElementType.LOCAL_VARIABLE: 局部变量声明
        ElementType.METHOD: 方法声明
        ElementType.PACKAGE: 包声明
        ElementType.PARAMETER: 参数声明
       ElementType.TYPE: 类、接口(包括注解类型)或enum声明


    @Documented将注解包含在JavaDoc中


    @Inheried允许子类继承父类中的注解

四、自定义注解及其应用
1)、定义一个最简单的注解
public @interface MyAnnotation {
    //......
}
2)、把注解加在某个类上:
@MyAnnotation
public class AnnotationTest{
    //......
}
以下为模拟案例
自定义注解@MyAnnotation


五、定义一个注解

package com.ljq.test;


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

@Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD, ElementType.TYPE})
  public @interface MyAnnotation {
     //为注解添加属性
      String color();
     String value() default "我是林计钦"; //为属性提供默认值
      int[] array() default {1, 2, 3}; 
     Gender gender() default Gender.MAN; //添加一个枚举
      MetaAnnotation metaAnnotation() default @MetaAnnotation(birthday="我的出身日期为1988-2-18");
     //添加枚举属性 
}


注解测试类AnnotationTest

package com.ljq.test;


 /**
 * 注解测试类
 * 
 * 
 * @author jiqinlin
 *
 */
 //调用注解并赋值
 @MyAnnotation(metaAnnotation=@MetaAnnotation(birthday = "我的出身日期为1988-2-18"),color="red", array={23, 26})
 public class AnnotationTest {


    public static void main(String[] args) {
        //检查类AnnotationTest是否含有@MyAnnotation注解
         if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)){
            //若存在就获取注解
             MyAnnotation annotation=(MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
            System.out.println(annotation);
            //获取注解属性
             System.out.println(annotation.color()); 
            System.out.println(annotation.value());
            //数组
             int[] arrs=annotation.array();
            for(int arr:arrs){
                System.out.println(arr);
            }
            //枚举
             Gender gender=annotation.gender();
            System.out.println("性别为:"+gender);
            //获取注解属性
             MetaAnnotation meta=annotation.metaAnnotation();
            System.out.println(meta.birthday());
        }
    }
}


枚举类Gender,模拟注解中添加枚举属性

package com.ljq.test;
 /**
 * 枚举,模拟注解中添加枚举属性
 * 
 * @author jiqinlin
 *
 */
 public enum Gender {
    MAN{
        public String getName(){return "男";}
    },
    WOMEN{
        public String getName(){return "女";}
    }; //记得有“;”
     public abstract String getName();
}


注解类MetaAnnotation,模拟注解中添加注解属性

package com.ljq.test;


 /**
 * 定义一个注解,模拟注解中添加注解属性
 * 
 * @author jiqinlin
 *
 */
 public @interface MetaAnnotation {
    String birthday();
}


六、基本内置注解

@Override
它的作用是对覆盖超类中方法的方法进行标记,如果被标记的方法并没有实际覆盖超类中的方法,则编译器会发出错误警告。
@Deprecated
它的作用是对不应该再使用的方法添加注解,当编程人员使用这些方法时,将会在编译时显示提示信息,它与javadoc里的@deprecated标记有相同的功能,准确的说,它还不如javadoc @deprecated,因为它不支持参数
@SuppressWarnings
其参数有:
deprecation,使用了过时的类或方法时的警告
unchecked,执行了未检查的转换时的警告
fallthrough,当 switch 程序块直接通往下一种情况而没有 break 时的警告
path,在类路径、源文件路径等中有不存在的路径时的警告
serial,当在可序列化的类上缺少serialVersionUID 定义时的警告
finally ,任何 finally 子句不能正常完成时的警告
all,关于以上所有情况的警告

七、自定义注解

它类似于新创建一个接口文件,但为了区分,我们需要将它声明为@interface,如下例:
1
2
3
Java代码
public @interface NewAnnotation {
}
使用自定义的注解类型
1
2
3
4
5
6
Java代码
public class AnnotationTest {
    @NewAnnotation
    public static void main(String[]args) {
    }
}
为自定义注解添加变量
1
2
3
4
Java代码
public @interface NewAnnotation {
    String value();
}
1
2
3
4
5
6
7
8
9
10
11
Java代码
public class AnnotationTest {
    @NewAnnotation("mainmethod")
    public static void main(String[]args) {
        saying();
    }
     
    @NewAnnotation(value="saymethod")
    public static void saying() {
    }
}
定义一个枚举类型,然后将参数设置为该枚举类型,并赋予默认值
1
2
3
4
5
6
7
8
9
public @interface Greeting {
    public enum FontColor {
        BLUE,
        RED,
        GREEN
    };
    String name();
    FontColor fontColor() default FontColor.RED;
}
这里有两种选择,其实变数也就是在赋予默认值的参数上,我们可以选择使用该默认值,也可以重新设置一个值来替换默认值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Java代码
public class AnnotationTest {
    @NewAnnotation("mainmethod")
    public static void main(String[]args) {
        saying();
        sayHelloWithDefaultFontColor();
        sayHelloWithRedFontColor();
    }
 
    @NewAnnotation("saymethod")
    public static void saying() {
    }
     
    // 此时的fontColor为默认的RED
    @Greeting(name="defaultfontcolor")
    public static void sayHelloWithDefaultFontColor() {
    }
 
    // 将fontColor改为BLUE
    @Greeting(name="notdefault", fontColor=Greeting.FontColor.BLUE)
    public static void sayHelloWithRedFontColor() {
    }
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:6593次
    • 积分:229
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:50篇
    • 译文:0篇
    • 评论:1条
    文章分类
    最新评论