注解(annotation),反射 - Java

> 注解原理及自定义注解
XML配置其实就是为了分离代码和配置而引入的。
Java SE5内置了三种标准注解:
@Override,表示当前的方法定义将覆盖超类中的方法。
@Deprecated,使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是不赞成使用的代码,被弃用的代码。
@SuppressWarnings,关闭不当编译器警告信息。

经过transient关键字修饰的字段是不能够被序列化的。

> 注解的使用:常用的     

 @Override,表示当前的方法定义将覆盖超类中的方法。

 @Deprecated,使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是不赞成使用的代码,被弃用的代码。
 @SuppressWarnings,关闭不当编译器警告信息。

    四个元注解分别是:@Target,@Retention,@Documented,@Inherited ,再次强调下元注解是java API提供,是专门用来定义注解的注解,其作用分别如下。
@Target : 表示该注解用于什么地方,可能的值在枚举类 ElemenetType 中,包括: 
          ElemenetType.CONSTRUCTOR        构造器声明 
          ElemenetType.FIELD               域声明(包括 enum 实例) 
          ElemenetType.LOCAL_VARIABLE     局部变量声明 
          ElemenetType.METHOD              方法声明 
          ElemenetType.PACKAGE             包声明 
          ElemenetType.PARAMETER             参数声明 
          ElemenetType.TYPE                类,接口(包括注解类型)或enum声明

@Retention : 表示在什么级别保存该注解信息。可选的参数值在枚举类型 RetentionPolicy 中,包括: 
          RetentionPolicy.SOURCE        注解将被编译器丢弃 
          RetentionPolicy.CLASS       注解在class文件中可用,但会被VM丢弃 
          RetentionPolicy.RUNTIME     VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。

@Documented : 将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。相当与@see,@param 等。

 @Inherited :允许子类继承父类中的注解。在您定义注解后并使用于程序代码上时,预设上父类别中的注解并不会被继承至子类别中,您可以在定义注解时加上java.lang.annotation.Inherited 限定的Annotation,这让您定义的Annotation型别被继承下来。注意注解继承只针对class 级别注解有效(这段建议看完全文后在来回顾)。 

> 使用注解应注意:

  1. 要用好注解,必须熟悉java 的反射机制,从上面的例子可以看出,注解的解析完全依赖于反射。
  2. 不要滥用注解。平常我们编程过程很少接触和使用注解,只有做设计,且不想让设计有过多的配置时。
  3. 注解的可用的类型包括以下几种:所有基本类型、String、Class、enum、Annotation、以上类型的数组形式。元素不能有不确定的值,即要么有默认值,要么在使用注解的时候提供元素的值。而且元素不能使用null作为默认值。注解在只有一个元素且该元素的名称是value的情况下,在使用注解的时候可以省略“value=”,直接写需要的值即可。 

 > 自定义注解,注解的使用示例:
 1> package Test0915;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** 
 *
 * @author  作者 :desaco
 *
 * @version 创建时间:2016-4-8 下午2:48:28 
 *
 */
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD,ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface TestA {
String name() ;
       int id() default 0;
       Class<Long> gid();
}

2> package Test0915;
import java.util.HashMap;
import java.util.Map;
/**
 * 
 * @author 作者 :desaco
 * 
 * @version 创建时间:2016-4-8 下午2:50:02
 * 
 */
@TestA(name = "type", gid = Long.class)
public class UserAnnotation {
@TestA(name = "param", id = 1, gid = Long.class)
// 使用了类成员注解
private Integer age;

@TestA(name = "construct", id = 2, gid = Long.class)
// 使用了构造方法注解
public UserAnnotation() {
}

@TestA(name = "public method", id = 3, gid = Long.class)
// 使用了 public 方法注解
public void a() {
Map<String, String> m = new HashMap<String, String>(0);
}

@TestA(name = "protected method", id = 4, gid = Long.class)
// protected 方法注解
protected void b() {
Map<String, String> m = new HashMap<String, String>(0);
}

@TestA(name = "private method ", id = 5, gid = Long.class)
// private 方法注解
private void c() {
Map<String, String> m = new HashMap<String, String>(0);

}

public void b(Integer a) {
}
  }


 3>  package Test0915;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
 * 
 * @author 作者 :desaco
 * 
 * @version 创建时间:2016-4-8 下午2:51:49
 * 
 */
public class ParseAnnotation {
/**
* 简单打印出UserAnnotation 类中所使用到的类注解 该方法只打印了 Type 类型的注解

* @throws ClassNotFoundException
*/
public static void parseTypeAnnotation() throws ClassNotFoundException {
Class clazz = Class.forName("Test0915.UserAnnotation");
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
TestA testA = (TestA) annotation;
System.out.println("type name = " + clazz.getName() + "  |  id = "+ testA.id() + "  |  name = " + testA.name()+ "  |  gid = " + testA.gid());
}
}

/**
* 简单打印出UserAnnotation 类中所使用到的方法注解 该方法只打印了 Method 类型的注解

* @throws ClassNotFoundException
*/
public static void parseMethodAnnotation() throws ClassNotFoundException {
Method[] methods = UserAnnotation.class.getDeclaredMethods();
for (Method method : methods) {
/*
* 判断方法中是否有指定注解类型的注解
*/
boolean hasAnnotation = method.isAnnotationPresent(TestA.class);
if (hasAnnotation) {
TestA annotation = method.getAnnotation(TestA.class);
System.out.println("method name = " + method.getName()+ "  |  id = " + annotation.id()+ "  |  description = " + annotation.name()+ "  |  gid = " + annotation.gid());
}
}
}

/**
* 简单打印出UserAnnotation 类中所使用到的构造方法注解 该方法只打印了 构造方法 类型的注解

* @throws ClassNotFoundException
*/
public static void parseConstructAnnotation() throws ClassNotFoundException {
Constructor[] constructors = UserAnnotation.class.getConstructors();
for (Constructor constructor : constructors) {
/*
* 判断构造方法中是否有指定注解类型的注解
*/
boolean hasAnnotation = constructor.isAnnotationPresent(TestA.class);
if (hasAnnotation) {
/*
* 根据注解类型返回方法的指定类型注解
*/
TestA annotation = (TestA) constructor.getAnnotation(TestA.class);
System.out.println("constructor = " + constructor.getName()+ "   |   id = " + annotation.id()+ "  |  description = " + annotation.name()+ "  |   gid= " + annotation.gid());
}
}
}

/**
* 简单打印出UserAnnotation 类中所使用到的字段注解 该方法只打印了 Method 类型的注解

* @throws ClassNotFoundException
*/
public static void parseFieldAnnotation() throws ClassNotFoundException {
Field[] fields = UserAnnotation.class.getDeclaredFields();
for (Field field : fields) {
boolean hasAnnotation = field.isAnnotationPresent(TestA.class);
if (hasAnnotation) {
TestA annotation = field.getAnnotation(TestA.class);
System.out.println("Field = " + field.getName() + "  |  id = "+ annotation.id() + "  |  description = "+ annotation.name() + "  |  gid= " + annotation.gid());
}
}
}

public static void main(String[] args) throws ClassNotFoundException {
System.out.println("------------------------------解析Type注解----------------------------------------------------------");
parseTypeAnnotation();
System.out.println("------------------------------解析Method注解-------------------------------------------------------");
parseMethodAnnotation();
System.out.println("------------------------------解析构造方法(Construct)注解------------------------------------------");
parseConstructAnnotation();
System.out.println("------------------------------解析字段(Field)注解-----------------------------------------------------");
parseFieldAnnotation();
}
}

 

-- 你能说说Java中的反射机制吗?- https://www.jianshu.com/p/e695b9a8b46f
 反射就是把Java的各种成分映射成相应的Java类。Class类的构造方法是private,由JVM创建。基本的 Java类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
 反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取他所有的成员变量和方法并且显示出来。
JavaBean 是 reflection 的实际应用之一,它能让一些工具可视化的操作软件组件。这些工具通过 reflection 动态的载入并取得 Java 组件(类) 的属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值