注解和反射

本贴最后更新于 848 天前,其中的信息可能已经斗转星移

1、注解

1.1、内置注解

  • @Override

子类重写方法

  • @Deprecated

标识这个方法或者类已经被废弃或有更好的选择

  • @SuppressWarnings

抑制编译器告警

1.2、元注解

元注解是用来修饰注解的注解

  • @Target

指定注释的使用范围

  • @Retention

注释的生命周期,有 SOURCE(编译时被抛弃),CLASS(class 文件中存在,但是运行时被抛弃),RUNTIME(运行时依然存在)

  • @Documented

标识生成 javadoc 时,该注解修饰的注解也会在 javadock 中显示

  • @Inherited

某个类使用了用 @Inherited 注解标识的注解,则他的子类也会继承这个注解

1.3、自定义注解

使用 @interface 定义注解

import java.lang.annotation.*;

@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotation {
    String[] names() default {};
}
@MyAnnotation(names = {"wenyl","zhaomt"})
public class BasicAnnotation {
}

2、反射

对于运行时的类,动态获取类信息,动态调用类的方法及属性的功能成为反射

2.1、获取 Class 对象

public class Person {
  
    public static void main(String[] args) throws ClassNotFoundException {
        // 直接通过类.class获取
        Class<Person> personClass = Person.class;

        // 通过类名获取
        Class<?> aClass1 = Class.forName("cn.com.wyl.study.reflection.Person");

        // 通过对象实例获取
        Person person = new Person();
        Class<? extends Person> aClass = person.getClass();
    }
  
}

3、反射获取泛型参数

通过反射获取传入的类的泛型实现如下,先定义一个泛型类

这里将获取传入的泛型的实际类型的方法写在构造函数里

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Calendar;

public abstract class BaseObject<T> {
    public BaseObject(){
        Type type = getClass().getGenericSuperclass();
        if( type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            type = parameterizedType.getActualTypeArguments()[0];
            if (type instanceof Class) {
                Class<T> type1 = (Class<T>) type;
                System.out.println(type1);
            }
        }


    }
    public abstract void insert(T t);
}

然后定义一个类来继承这个抽象类

public class TargetObject1 extends BaseObject<Integer>{

    public void insert(Integer integer) {

    }
}

最后我们创建对象

    public static void main(String[] args) throws ClassNotFoundException {
        BaseObject<Integer> baseObject = new TargetObject1();
    }

在初始化的时候会调用抽象类的构造函数获取传入的泛型的实际类型

4、反射获取注解

参照 hibernate 自定义两个注解

@Table(tableName = "person")
public class Person {
    @Column(columnName = "person_name",columnType = "varchar",length = 255)
    private String personName;

    public Person(){}
    public Person(String personName) {
        this.personName = personName;
    }

    public String getPersonName() {
        return personName;
    }

    public void setPersonName(String personName) {
        this.personName = personName;
    }

}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
    String tableName();
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Column{
    String columnName();
    int length() default 32;
    String columnType() default "varchar";
}

获取注解如下

    public static void main(String[] args) throws Exception{
        // 获取类注解
        Person person = new Person();
        Table annotation = person.getClass().getAnnotation(Table.class);
        System.out.println(annotation.tableName());

        // 获取属性注解
        Field field = person.getClass().getDeclaredField("personName");
        Column column = field.getAnnotation(Column.class);
        System.out.println(column.columnName());
        System.out.println(column.columnType());
        System.out.println(column.length());
    }

这里都是获取指定注解,需要获取所有注解使用 getAnnotations()方法,获取方法的注解可以先获取方法在获取方法上的注解(参照获取属性)

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3167 引用 • 8207 回帖
  • 反射
    18 引用 • 29 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...