java 泛型 注解_JAVA注解,泛型,反射

  • Post author:
  • Post category:java

一、注解

元注解

元注解是用来修饰注解的注解,java提供了3种元注解。

@Retention

RetentionPolicy.SOURCE

表明注解仅存在源码之中,不存在.class文件中,更不能运行时可见。常见的注解为@Override, @SuppressWarnings等。

RetentionPolicy.CLASS

这是默认的注解保留策略。这种策略下,注解将存在于.class文件中,但是不能被运行时访问。通常这种注解策略用来处理一些字节码级别的操作。

RetentionPolicy.RUNTIME

这种策略下可以被运行时访问到。通常情况下,我们都会结合反射来做一些事情。

@Target

注解修饰的位置

@Inherited

注解是否可以被子类继承

自定义注解

如下定义了一个MyAnnotation注解

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.TYPE,ElementType.FIELD})

@Inherited

public @interface MyAnnotation {

String name();

String value() default “”;

}

二、泛型

Java采用泛型擦除机制来引入泛型。Java中的泛型仅仅是给编译器Javac使用的,确保数据的安全性和免去强制类型转换的麻烦。但是编译一旦完成,所有和泛型有关的类型全部被擦除。类型擦除机制存在的原因正是因为如果在运行时存在泛型,那么将要修改JVM指令集,这是非常致命的。

原始类型会生成字节码文件对象,而泛型类型相关的类型并不会生成与其相对应的字节码文件(因为泛型类型将会被擦除),因此,无法将泛型相关的新类型与class相统一。因此,为了程序的扩展性以及为了开发需要去反射操作这些类型,就引入了Type这个类型,并且新增了ParameterizedType, TypeVariable, GenericArrayType, WildcardType四个表示泛型相关的类型,再加上Class,这样就可以用Type类型的参数来接受以上五种子类的实参或者返回值类型就是Type类型的参数。统一了与泛型有关的类型和原始类型Class。而且这样一来,我们也可以通过反射获取泛型类型参数。

tips:

ParameterizedType:参数化类型,比如List<>。

GenericArrayType:泛型数组类型,比如比如List<>[],T[]这种。

TypeVariable:泛型变量,泛型信息在编译时会被转换为一个特定的类型, 而TypeVariable就是用来反映在编译前该泛型的信息。即我们常用的T,K这种泛型变量。

WildcardType:通配符类型,比如?、? extends Number、? super Integer。

三、反射获取注解,泛型信息

通过反射获取类,方法,参数里面的注解和泛型信息,示例如下。

@MyAnnotation(name = “zhangsan”)

public class User {

private String name;

public void sayHi() {

System.out.println(“hi:i am ” + name);

}

public void sayHi(String age,T t) {

System.out.println(“i am “+ name + “,and i am ” + age + “year old,and t is”+ t);

}

public static void main(String[] args) throws Exception {

Class clazz = User.class;

/**

* 获取类模板信息

*/

// 获取自有属性

Field[] fields = clazz.getDeclaredFields();

// 获取自有方法

Method[] methods = clazz.getDeclaredMethods();

// 获取构造器

Constructor>[] constructors = clazz.getDeclaredConstructors();

/**

* 执行方法,修改属性

*/

// 新建对象

Constructor constructor = clazz.getDeclaredConstructor();

User xiaoming = constructor.newInstance();

// 修改属性

Field field = clazz.getDeclaredField(“name”);// public的属性

field.setAccessible(true);

field.set(xiaoming, “xiaoming”);

field.setAccessible(false);

// 调用方法

Method method = clazz.getDeclaredMethod(“sayHi”, null);

method.invoke(xiaoming, new Class>[] {});

/**

* 获取注解

*/

//获取修饰类的注解

Annotation[] annotations = clazz.getAnnotations();

/**

* 获取泛型信息

*/

//获取方法参数的泛型信息

Method tMethod = clazz.getDeclaredMethod(“sayHi”,new Class[]{String.class,Object.class});

Type[] types = tMethod.getGenericParameterTypes();

for (Type type : types) {

System.out.println(type.getTypeName());

if (type instanceof TypeVariable) {

TypeVariable typeVariable = (TypeVariable) type;

System.out.println(“TypeVariable:”+typeVariable.getName());

}

}

}

}


版权声明:本文为weixin_33195162原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。