注解和反射

注解和反射 – 简笔

1.内置注解

  • @Override 重写超类的方法
  • @Deprecated 不推荐使用,但是可以使用
  • @SuppressWarning 镇压警告 可以使用的参数有 all

2.元注解

元注解是就是解释其他注解的注解 meta-annotation

  • @Target 描述注解的使用范围
	TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
  • @Retention 描述注解的生命周期 Runtime>Class>Sources
  • @Document 该注解将被包含到javadoc中
  • @Inherited 说明子类可以继承父类中的该注解

3.自定义注解

// 注解可以显示赋值
// 如果没默认值就一定要现实赋值
// 默认值-1表示不存在
// 如果只有一个参数,并且名为value,那么赋值的时候可以省略value
// 格式 自动继承java.lang.annotation.Annotation接口
public @interface XXX {
    // 定义内容
    ElementType[] value(); // 参数 类型只能是 基本类型,Class,Sting,enum  以括号结尾() 后面可以跟default 来给一个默认值
}

4.反射机制

java不是动态语言,可以称为"准动态语言",具有一定的动态性

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

4.1 创建class类的方式

  • 对象.getClass()
  • 类.class
  • forName(类的全路径)
  • 内置对象包装类.TYPE

4.2 哪些类型有Class对象

  • class
  • interface
  • 数组
  • enum
  • annotation
  • primitive type
  • void

ps:对于数组来说,只有维度和长度一样,Class就一样

4.4 类加载器

类加载的作用

将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后再堆中生成一个代表这个类的Class对象,作为方法区中类数据的访问入口.

类缓存

标准的javaSE类加载器可以按要求查找类,但一旦某个类加载到类加载器中,它将加载(缓存)一段时间.不过jvm(gc)垃圾回收机制可以回收这些Class对象.

类加载器的类型

  • 引导类加载器 是C++写的,无法直接获取
  • 拓展类加载器
  • 系统类加载器

双亲委派机制

如果引导类加载器和拓展类加载器中含有自己写的同名的class,那么会优先使用其中的类,而不是自己写的类(保证安全)

4.5 获取运行时类的结构

  • 获取类的属性
getFields()         获取所有的public属性
getDeclaredFields()  获取所有的属性
  • 获得类的方法
getMethods()          获取本类以及父类的所有方法
getDeclaredMethods()  获取本类的所有方法

4.6 通过反射动态创建对象

创建类的对象

调用Class对象的newInstance()方法

  • 类必须有一个无参构造函数
  • 类的构造器访问权限要足够
newInstance()  // 实际是调用无参构造器
  • 可以通过获取构造器来创建对象

4.7 提升效率

如果一个反射语句需要反复调用,那么调用setAccessible(true)方法可以提升其执行效率

本质上,是关闭了安全检测

4.8 反射操作泛型

测试demo

package reflection;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class Test02 {
    public static List<Integer> fun(Map<Integer, String> map){
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        Method method = Test02.class.getDeclaredMethod("fun", Map.class);

        // 获取泛型方法的输入参数
        Type[] types = method.getGenericParameterTypes();
        for (Type type : types) {
            System.out.println(type);
            if (type instanceof ParameterizedType){
                Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }
        }

        // 获取泛型方法的返回参数
        Type type = method.getGenericReturnType();
        System.out.println(type);
        if (type instanceof ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }
        
    }
}

结果集合

java.util.Map<java.lang.Integer, java.lang.String>
class java.lang.Integer
class java.lang.String
java.util.List<java.lang.Integer>
class java.lang.Integer

4.9 获取注解

orm

Object relationship Mapping -> 对象关系映射

  • 类和表结构对应
  • 属性和字段对应
  • 对象和记录对应

demo

package reflection;

import java.lang.annotation.*;

public class Test03 {
    public static void main(String[] args) throws NoSuchFieldException {
        Class clzz = People.class;

        // 通过反射获得注解
        Annotation[] annotations = clzz.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        // 获取注解的value
        Table table = (Table)clzz.getAnnotation(Table.class);
        System.out.println(table.value());

        // 获得类指定注解
        java.lang.reflect.Field id = clzz.getDeclaredField("id");
        Field field = id.getAnnotation(Field.class);
        System.out.println(field.name());
        System.out.println(field.type());
        System.out.println(field.len());

    }
}

@Table("people")
class People{
    @Field(name = "id", type = "int", len = 10)
    private int id;
    @Field(name = "name", type = "varchar", len = 20)
    private String name;
    @Field(name = "age", type = "int", len = 10)
    private int age;

    public People() {
    }

    public People(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "People{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

// 类名注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
    String value();
}

// 属性注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Field{
    String name();
    String type();
    int len();
}

结果

@reflection.Table(value=people)
people
id
int
10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值