注解与反射

注解

元注解

@ Target:用于描述注解的使用范围
@Rutention:表示需要在什么级别保存该注释信息,用于描述注解的声明周期
(SOURCE<CLASS<RUNTIME)

自定义注解

@interface用来声明一个注解:public @interface 注解名 {定义内容}

public class Annotation {
    @MyAnnotation("")
    public  String test(){
        return "注解";
    }

@MyAnnotation2(age = 18,value ={"HKU"})
    public  String test2(){
        return "注解";
    }

    @Target({ElementType.METHOD,ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
//    @Retention(RetentionPolicy.CLASS)
//    @Retention(RetentionPolicy.SOURCE)
    public @interface MyAnnotation{
        String value();
    }
    @Target({ElementType.METHOD,ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation2{
        int age();
        String name() default "Chet";
        //传对象
        String[] value();
    }
}

反射

创建对象方式

  • 正常方式
引入需要的`包类`名称
通过new实例化
取得实例化对象
  • 反射方式
实例化对象
getClass方法
得到完整的`包类`名称

获取Class类的实例

  • 已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
        Class<User> clazz = User.class;
  • 已知某个类的实例,调用该实例的getClass()方法获取Class对象,调用该实例的getSuperclass()方法获取该Class对象的父对象Class
        Class clazz = user.getClass();       
        Class superclass = clazz.getSuperclass();     
  • 已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException
        Class userClass = Class.forName("com.refelction.User");

获取实例化对象

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.lang.reflect.InvocationTargetException;
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取类名
        Class userClass = Class.forName("com.refelction.User");
        System.out.println(userClass);
        //获取实例化对象
        User user = (User) userClass.getDeclaredConstructor().newInstance();
        user.setAge(1);
        user.setId(2);
        user.setName("Chet");
        System.out.println(user);
    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class User{
    private String name;
    private Integer age;
    private Integer id;
}

所有类型的Class对象

public class test2 {
    public static void main(String[] args) {
        Class<Object> objectClass = Object.class;//类
        System.out.println(objectClass);
        Class<Comparable> comparableClass = Comparable.class;//接口
        System.out.println(comparableClass);
        Class<String[]> stringArr = String[].class;//一维数组
        System.out.println(stringArr);
        Class<int[][]> intArrArr = int[][].class;//二维数组
        System.out.println(intArrArr);
        Class<Override> overrideClass = Override.class;//注解
        System.out.println(overrideClass);
        Class<ElementType> elementTypeClass = ElementType.class;//枚举
        System.out.println(elementTypeClass);
        Class<Integer> integerClass = Integer.class;//基本数据类型
        System.out.println(integerClass);
        Class<Void> voidClass = void.class;//void
        System.out.println(voidClass);
        Class<Class> classClass = Class.class;//Class
        System.out.println(classClass);
    }
}
  • 输出
class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.lang.Override
class java.lang.annotation.ElementType
class java.lang.Integer
void
class java.lang.Class

Process finished with exit code 0

类加载内存分析

加载

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

链接

  • 将Java类的二进制代码合并到JVM的运行状态之中的过程

初始化

ClassLoader

  public static void main(String[] args) throws ClassNotFoundException {
        //获取系统类加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);
        //获取系统类加载器的父类加载器--扩展类加载器
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);
        //获取扩展类加载器的父类加载器--根加载器
        ClassLoader grand = parent.getParent();
        System.out.println(grand);
        //测试加载当前类的类加载器
        ClassLoader classLoader1 = Class.forName("com.refelction.Test").getClassLoader();
        System.out.println("com.refelction.Test的 classLoader"+classLoader1);
        ClassLoader classLoader2 = Class.forName("java.lang.Object").getClassLoader();
        System.out.println("java.lang.Object的 classLoader="+classLoader2);
    }
  • 输出
jdk.internal.loader.ClassLoaders$AppClassLoader@78308db1
jdk.internal.loader.ClassLoaders$PlatformClassLoader@2e817b38
null
com.refelction.Test的 classLoader=jdk.internal.loader.ClassLoaders$AppClassLoader@78308db1
java.lang.Object的 classLoader=null

获取类的运行时结构

  • User类
@Data
@NoArgsConstructor
@AllArgsConstructor
class User{
    public String name;
    private Integer age;
    private Integer id;
}
  • 获取结构
  public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class userClass = Class.forName("com.refelction.User");
        //包名+类名
        String name = userClass.getName();
        System.out.println(name);
        System.out.println("=======================");
        //类名
        String simpleName = userClass.getSimpleName();
        System.out.println(simpleName);
        System.out.println("=======================");
        Field[] fields1 = userClass.getFields();//只能找到public属性
        for (Field field : fields1) {
            System.out.println(field);
        }
        System.out.println("=======================");
        Field[] fields2 = userClass.getDeclaredFields();//可以找到全部属性
        for (Field field : fields2) {
            System.out.println(field);
        }
        System.out.println("=======================");
        Field fieldName = userClass.getField("name");
        System.out.println("fieldName" + fieldName);
        //获取不到private属性,报错
        // Field fieldAge = userClass.getField("age");
        Field fieldAge = userClass.getDeclaredField("age");
        System.out.println("fieldAge=" + fieldAge);
        System.out.println("=======================");
        Method[] methods = userClass.getMethods();//获得本类和父类的public方法
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("=======================");
        Method[] declaredMethods = userClass.getDeclaredMethods();//获得本类的所有方法
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("=======================");
        //获得指定名称方法
        Method getName = userClass.getDeclaredMethod("getName");
        System.out.println(getName);
        Method getAge = userClass.getMethod("getAge");
        System.out.println(getAge);
        System.out.println("=======================");
        //获得所有的构造器
        Constructor[] constructors = userClass.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        Constructor[] declaredConstructors = userClass.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
        System.out.println("=======================");
        //获取有参构造器
        Constructor constructor1 = userClass.getConstructor(String.class, Integer.class, Integer.class);
        System.out.println(constructor1);
        Constructor declaredConstructor1 = userClass.getDeclaredConstructor(String.class, Integer.class, Integer.class);
        System.out.println(declaredConstructor1);
        //获取无参构造器
        Constructor constructor2 = userClass.getConstructor();
        System.out.println(constructor2);
        Constructor declaredConstructor2 = userClass.getDeclaredConstructor();
        System.out.println(declaredConstructor2);
    }

动态创建对象执行方法

  public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        Class<User> userClass = User.class;
        User user = userClass.getDeclaredConstructor().newInstance();//调用了无参构造器
        user.setName("Chet");
        user.setId(1);
        user.setAge(18);
        System.out.println(user);
        //得到有参构造方法
        Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class, Integer.class, Integer.class);
        User user1 = declaredConstructor.newInstance("Atkins",2,34);
        System.out.println(user1);
        //通过反射得到方法
        //1.获取实例化对象
        User user2 = userClass.getDeclaredConstructor().newInstance();
        //2.得到实例化对象的setAge方法
        Method setAge = userClass.getDeclaredMethod("setAge", Integer.class);
        //3.方法.invoke(实例化对象,参数)
        setAge.invoke(user2, 25);
        System.out.println(user2);

        //通过反射得到方法
        Field id = userClass.getDeclaredField("id");
        //id为private属性,需要设置为可以访问,默认访问开关为false
        id.setAccessible(true);
        id.set(user2,3);
        Field name = userClass.getDeclaredField("name");
//       name为public属性,不需要开启name.setAccessible(true);
        name.set(user2,"MJ");
        System.out.println(user2);
    }

性能检测

public class Test6 {
    public static  void  main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        test1();
        test2();
        test3();
    }
    //普通方式调用
    public static void test1() {
        User user = new User();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            user.getName();
        }
        long end = System.currentTimeMillis();
        long time = end - start;
        System.out.println(time);
    }

    //反射方式调用
    public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        long start = System.currentTimeMillis();
        Class userClass = user.getClass();
        Method getName = userClass.getDeclaredMethod("getName");
        for (int i = 0; i < 1000000000; i++) {
           getName.invoke(user);
        }
        long end = System.currentTimeMillis();
        long time = end - start;
        System.out.println(time);
    }

    //反射方式调用,关闭检测
    public static  void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        long start = System.currentTimeMillis();
        Class userClass = user.getClass();
        Method getName = userClass.getDeclaredMethod("getName");
        getName.setAccessible(true);
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user);
        }
        long end = System.currentTimeMillis();
        long time = end - start;
        System.out.println(time);
    }
}

反射操作泛型

  • ParameterizedType:表示一种参数化类型,比如Collection<String>
  • GenericArrayType:表示一种元素类型时参数化类型或者类型变量的数组类型
  • TypeVariable:是各种变量的公共父接口
  • WildcardType:代表一种通配符类型表达式

获取注解的值

@Annotation.MyAnnotation2(age = 28,value ={"HK","UK"})
public class Annotation {
    public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException {
        //通过一个类的属性获取一个类的注解的值
        //1.获取一个类的class
        Class<Teacher> teacherClass = Teacher.class;
        //2.获取该类的属性
        Field name = teacherClass.getDeclaredField("name");
        //3.通过该属性获取其指定注解
        MyAnnotation2 annotation = name.getAnnotation(MyAnnotation2.class);
        //4.获取指定注解的值
        String[] annotationValue = annotation.value();
        for (String s : annotationValue) {
            System.out.println(s);
        }
        System.out.println(annotation.age());
        
        //通过一个类获取类的值
        //1.获取一个类的class
        Class<Annotation> annotationClass = Annotation.class;
        //2.获取该类的注解
        MyAnnotation2 annotation2 = annotationClass.getAnnotation(MyAnnotation2.class);
        //3.获取指定注解的值
        String[] value = annotation2.value();
        for (String s : value) {
            System.out.println(s);
        }
        int age = annotation2.age();
        System.out.println(age);
    }
    @Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation2{
        int age();
        String name() default "Chet";
        //传对象
        String[] value();
    }
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    class Teacher{
        @MyAnnotation2(age = 18,value ={"HKU"})
        String name;
        Integer age;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值