注解反射

在这里插入图片描述
什么时候会发生类初始化
在这里插入图片描述
在这里插入图片描述

获得加载器的方式 类.getClassLoader
获得加载器的路径 在这里插入图片描述
Mybatis,Spring 框架底层的部分

注解

类似于@Override重写

注解有检查和约束的作用,可以被其他程序访问,可以在package,class,method,field等上面,相当于添加了额外的辅助信息,可以通过反射机制编程实现对这些元数据的访问.

内置注解

加在想要操作的方法上面

@Override重写

@Deprecated 废弃,不推荐使用但是可以使用

@SuppressWarnings(“all”),镇压警告,不再显示警告,参数可以改变

元注解

负责解释其他注解的注解,定义注解

格式 public @interface 注解名{//如果在类的内部申请不带public

定义内容

}

public class test02 {
   @MyAnnotation
    public void test(){

    }
}
 //定义一个注解
// Target表示可以用在哪些地方
@Target(value ={ElementType.METHOD,ElementType.TYPE})
 //Retention表示注解在什么地方有效,RunTime>class>source
@Retention(RetentionPolicy.RUNTIME)D
//Documented表示将注解是否生成到JAVAdoc中
@Documented
//Inherited写了表示子类可以继承父类的注解
@Inherited
 //定义的注解
@interface MyAnnotation{

}

自定义注解

其中的每一个方法实际上是声明了一个配置参数.方法的名称就是参数的名称.
返回值类型就是参数的类型(返回值只能是基本类型,Class , String , enum ).可以通过default来声明参数的默认值
如果只有一个参数成员,一般参数名为value,
注解元素必须要有值﹐我们定义注解元素时,经常使用空字符串,0作为默认值.

String str();
int ID();

带default默认值的参数可以不写,但是不带default的参数必须写

String str() default "";
int ID() default 0;

反射

动态语言:在程序运行时能改变代码的内部结构并且能直接操作内部的属性 其中反射机制为Java被视为动态语言的关键

正常方式 导入包-> new 实例化->取得对象

反射方式 实例化对象->getclass()方法->得到完整的包类名称

反射机制提供的功能

在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时获取泛型信息
在运行时调用任意一个对象的成员变量和方法
在运行时处理注解
生成动态代理

Class c1 = Class.forName("test.User");//写类名
Class c2 = Class.forName("test.User");
Class c3 = Class.forName("test.User");
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
//一个类只生成一个class文件,所以哈希值一样

得到class类的几种方式

  1. .getSuperclass 获得父类class

  2. 直接对象名/类名.class

Class<User> userClass = User.class;
  1. 知道类的路径

    Class c1 = Class.forName(“test.User”);//写类名

  2. 内置对象的包装类

    Integer.TYPE

class内存分析

  1. 加载到内存,产生一个对应的classduixiang
  2. 链接,连接结束后属性会被赋一个默认值
  3. 初始化,加载代码

反射中获得对象,操作对象

 Class<?> c1 = Class.forName("test.User");
        User user = (User) c1.newInstance();//调用无参构造器,构造对象
        //如果没有无参构造器,通过构造器创建对象
        Constructor constructor = c1.getDeclaredConstructor(String.class,int.class);
      User wpx = (User) constructor.newInstance("wpx", 20);//通过这个构造器传参
       System.out.println(wpx);
//通过反射操作方法
        User user2 = (User) c1.newInstance();
        //通过反射获取方法
        Method setname  = c1.getDeclaredMethod("setName", String.class);
        Method setid = c1.getDeclaredMethod("setID", int.class);
        //invoke (对象,方法值)激活
        setname.invoke(user2,"wpx");
        setid.invoke(user2,22);
        System.out.println(user2);

User{name='wpx', ID=22}
其他方法类似
//通过反射操作属性
        User user3 = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");
        //不能直接操作私有属性,需要关闭安全检测
        name.setAccessible(true);
        name.set(user3,"wpx");
        System.out.println(user3.getName());
//其他属性类似

设置setAccessible(true); 提高反应效率

性能对比

public class ReflectionMin {
    //普通方法
    public static void test1(){
        User user = new User();
        long starTime =  System.currentTimeMillis();//开始计时
        for (int i = 0; i < 1000000000; i++) {
            user.getName();
        }
       long endTime= System.currentTimeMillis();//结束计时
        System.out.println("普通方法执行十亿次用时"+(endTime-starTime)+"ms");
    }
    //反射方法
    public static  void  test2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class c1 = Class.forName("test.User");
        User user = (User) c1.newInstance();//通过反射方式创建对象,也可以直接new user
        Method getName = c1.getDeclaredMethod("getName",null);//获取方法

        long starTime =  System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
           getName.invoke(user,null);//启动方法获得对象 ,因为get的构造器没有参数所以为空
        }
        long endTime= System.currentTimeMillis();
        System.out.println("反射方法执行十亿次用时"+(endTime-starTime)+"ms");
    }
    //关闭安全检测
    public static  void  test3() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class c1 = Class.forName("test.User");
        User user = (User) c1.newInstance();
        Method getName = c1.getDeclaredMethod("getName",null);
        getName.setAccessible(true);//关闭
        long starTime =  System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }
        long endTime= System.currentTimeMillis();
        System.out.println("反射方法执行十亿次用时"+(endTime-starTime)+"ms");
    }


    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        test1();
        test2();
        test3();
    }
}

运行结果

普通方法执行十亿次用时3ms
反射方法执行十亿次用时2371ms
反射方法执行十亿次用时1288ms

反射操作注解ORM

package test;

import java.lang.annotation.*;

public class test10 {
//反射操作注解
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
    Class<?> c1 = Class.forName("test.student");
    //通过反射获得注解
    Annotation[] annotations = c1.getAnnotations();
    for (Annotation annotation : annotations) {
        System.out.println(annotation);
    }
    //通过反射获得注解的value值
    table table = c1.getAnnotation(table.class);
    String value = table.value();
    System.out.println(value);
    //获得类指定注解
    java.lang.reflect.Field field = c1.getDeclaredField("name");
    Field file = field.getAnnotation(Field.class);
    System.out.println(file.Columnname());
    System.out.println(file.type());
    System.out.println(file.length());

}



}
//简单实体类
@table("db_student")
class student{
    @Field(Columnname = "db_name",type ="varchar",length = 255)
    private String name;
    @Field(Columnname = "db_id",type ="int",length = 10)
    private int id;
    @Field(Columnname = "db_age",type ="int",length = 10)
    private int age;

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

    public student() {
    }

    public student(String name, int id, int age) {

        this.name = name;
        this.id = id;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
//自定义注解
//类的注解
@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@interface table{
String value();
}
/**
 * @author 17699
 */ //属性的注解
@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)
@interface Field {
    String Columnname();
    String type();
    int length();
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值