侧边栏壁纸
博主头像
这就是之谦博主等级

我们的征途是星辰大海

  • 累计撰写 182 篇文章
  • 累计创建 3 个标签
  • 累计收到 16 条评论
标签搜索

目 录CONTENT

文章目录

注解和反射

这就是之谦
2021-08-26 / 0 评论 / 0 点赞 / 482 阅读 / 18,185 字
温馨提示:
本文最后更新于 2021-11-14,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

自定义注解

package com.badwei.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


// 自定义注解
public class Test03 {

    //注解可以显式赋值,如果没有默认值,我们就必须给注解赋值
    @MyAnnotation(name = "lxw")
    public void test(){

    }

}

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
    // 注解的参数:参数类型+参数名();
    String name() default "";
    int age() default 0;
    int id() default -1;
    String[] schools() default {"清华","北大"};


}

Java反射机制

1、反射

image-20210826154147218

2、Class类

image-20210826160148450

3、Class类的常用方法

image-20210826160243449

4、获取Class类的实例

image-20210826161551520

测试代码:

package com.badwei.reflection;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

// 测试class类的创建方式有哪些
public class Test03 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println(person);

        // 方式一:通过对象获得
        Class c1 = person.getClass();
        System.out.println("c1=>"+c1+" hashCode=" + c1.hashCode());

        //方式二:通过forName获得
        Class c2 = Class.forName("com.badwei.reflection.Student");
        System.out.println("c2=>"+c2+" hashCode=" + c2.hashCode());

        //方式三:通过类名.Class获得
        Class<Student> c3 = Student.class;
        System.out.println("c3=>"+c3+" hashCode=" + c3.hashCode());

        //方式四:基本数据类型的包装类都有一个TYPE属性
        Class<Integer> integerClass = Integer.TYPE;
        System.out.println("integerClass=>"+integerClass);

        // 获得父类类型
        Class c5 = c1.getSuperclass();
        System.out.println("c5=>"+c5+" hashCode=" + c5.hashCode());


    }


}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Person{
    private String name;
}

class Student extends Person{
    public Student(){
        this.setName("学生");
    }
}

class Teacher extends Person{
    public Teacher(){
        this.setName("老师");
    }
}

5、那些类型可以有class对象

image-20210826162741243

测试

package com.badwei.reflection;

import java.lang.annotation.ElementType;

// 所有类型的class
public class Test04 {

    public static void main(String[] args) {
        Class<Object> c1 = Object.class; //类
        Class<Comparable> c2 = Comparable.class; //接口
        Class<String[]> c3 = String[].class; //一位数组
        Class<int[][]> c4 = int[][].class; //二维数组
        Class<Override> c5 = Override.class; //注解
        Class<ElementType> c6 = ElementType.class; //枚举
        Class<Integer> c7 = Integer.class; //基本数据类型包装类
        Class<Void> c8 = void.class; //void
        Class<Class> c9 = Class.class; //Class

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);

    }
}

输出:

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

6、Java内存分析

image-20210826163514428

7、类的加载

image-20210826165914344

8、对象和类的创建内存分析

image-20210826164813823

package com.badwei.reflection;


public class Test05 {

    public static void main(String[] args) {
        A a = new A();
        System.out.println(A.m);

        /*
        1.加载到内存,会产生一个类对应的额Class对象
        2.连接,链接结束后 m=0
        3.初始化
        <clinit>(){
            System.out.println("A静态代码块初始化");
            m = 300;
            m = 100;
        }
        m=100
         */

    }

}

class A{
    static {
        System.out.println("A静态代码块初始化");
        m = 300;
    }

    static int m =100;

    public A(){
        System.out.println("A的无参构造器");
    }
}

输出:

A静态代码块初始化
A的无参构造器
100

9、什么时候会发生类的初始化

image-20210826170002219

10、分析类的初始化

package com.badwei.reflection;

// 测试类什么时候会初始化
public class Test06 {
    static {
        System.out.println("main加载");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        // 1.主动引用
        // Son son = new Son();
         /*
         输出:
         main加载
        父类加载
        子类加载
          */
        

        //反射也会产生主动引用
        // Class<?> aClass = Class.forName("com.badwei.reflection.Son");
        /*
         输出:
         main加载
        父类加载
        子类加载
          */
        

        //不会产生类的引用的方法 -子类调用父类的静态方法和变量,子类不会被加载
        // System.out.println(Son.b);
         /*
         输出:
         main加载
         父类加载
         2
          */

        
        //只是一个数组空间,不会初始化
        // Son[] sons = new Son[5];
        /*
        输出:
        main加载
         */
        

        // System.out.println(Son.M);
        /*
        输出:
        main加载
        1
         */

    }
}


class Father{

    static int b = 2;

    static{
        System.out.println("父类加载");
    }
}

class Son extends Father{
    static {
        System.out.println("子类加载");
        m = 300;
    }
    static int m = 100;
    static final int M = 1;
}

输出:

main加载
父类加载
子类加载

11、类加载的作用

image-20210826173016321

12、获取类加载器

package com.badwei.reflection;

public class Test7 {
    public static void main(String[] args) throws ClassNotFoundException {

        // 获取系统类加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader); //sun.misc.Launcher$AppClassLoader@18b4aac2

        //获取系统类加载器的父类加载器-->拓展类加载器
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent); //sun.misc.Launcher$ExtClassLoader@74a14482

        //获取拓展类加载器的父类加载器-->根加载器(C/C++) 【java无法获取】
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1); //null

        //测试当前类是哪个加载器加载的
        ClassLoader classLoader = Class.forName("com.badwei.reflection.Test7").getClassLoader();
        System.out.println(classLoader); //sun.misc.Launcher$AppClassLoader@18b4aac2

        //测试JDK内置的类是谁加载的 【是由根加载器加载的】
        ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader1); //null

        //如何获得系统类加载器可以加载的路径
        String property = System.getProperty("java.class.path");
        System.out.println(property);
        /*
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\charsets.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\deploy.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\access-bridge-64.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\cldrdata.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\dnsns.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jaccess.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jfxrt.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\localedata.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\nashorn.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunec.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunjce_provider.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunmscapi.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunpkcs11.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\zipfs.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\javaws.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\jce.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\jfr.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\jfxswt.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\jsse.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\management-agent.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\plugin.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\resources.jar;
        D:\Program Files\Java\jdk1.8.0_221\jre\lib\rt.jar;
        D:\idea-study\注解和反射\target\classes;
        C:\Users\12113\.m2\repository\org\projectlombok\lombok\1.18.20\lombok-1.18.20.jar;
        D:\Program Files\JetBrains\IntelliJ IDEA 2021.1.1\lib\idea_rt.jar
         */


    }
}

13、获取运行类的结构

package com.badwei.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

// 获得运行时类的信息
public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {

        Class<?> c1 = Class.forName("com.badwei.reflection.User");

        //获得类的名字
        System.out.println(c1.getName());
        System.out.println(c1.getSimpleName());

        //获得类的属性
        Field[] fields = c1.getFields(); //只能找到public属性

        fields = c1.getDeclaredFields(); //找到所有属性
        for (Field field : fields) {
            System.out.println(field);
        }

        //获得指定属性的值
        Field name = c1.getDeclaredField("username");
        System.out.println(name);

        //获得类的方法
        Method[] methods = c1.getMethods(); //获得本类及其父类的全部public方法
        for (Method method : methods) {
            System.out.println("getMethods=>"+method);
        }

        Method[] declaredMethods = c1.getDeclaredMethods(); //获得本类的所有方法
        for (Method declaredMethod : declaredMethods) {
            System.out.println("getDeclaredMethods=>"+declaredMethod);
        }

        //获得指定的方法
        Method getUsername = c1.getMethod("getUsername", null);
        Method setUsername = c1.getMethod("setUsername", String.class);
        System.out.println(getUsername);
        System.out.println(setUsername);

        //获得指定的构造器
        Constructor<?>[] constructors = c1.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("getConstructors=>"+constructor);
        }
        Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("getDeclaredConstructors=>"+declaredConstructor);
        }

        //获得指定的构造器
        Constructor<?> declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        System.out.println(declaredConstructor);


    }
}

输出结果:

com.badwei.reflection.User
User
private java.lang.String com.badwei.reflection.User.username
private int com.badwei.reflection.User.id
private int com.badwei.reflection.User.age
private java.lang.String com.badwei.reflection.User.username
getMethods=>public boolean com.badwei.reflection.User.equals(java.lang.Object)
getMethods=>public java.lang.String com.badwei.reflection.User.toString()
getMethods=>public int com.badwei.reflection.User.hashCode()
getMethods=>public int com.badwei.reflection.User.getId()
getMethods=>public int com.badwei.reflection.User.getAge()
getMethods=>public void com.badwei.reflection.User.setId(int)
getMethods=>public void com.badwei.reflection.User.setAge(int)
getMethods=>public java.lang.String com.badwei.reflection.User.getUsername()
getMethods=>public void com.badwei.reflection.User.setUsername(java.lang.String)
getMethods=>public final void java.lang.Object.wait() throws java.lang.InterruptedException
getMethods=>public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
getMethods=>public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
getMethods=>public final native java.lang.Class java.lang.Object.getClass()
getMethods=>public final native void java.lang.Object.notify()
getMethods=>public final native void java.lang.Object.notifyAll()
getDeclaredMethods=>public boolean com.badwei.reflection.User.equals(java.lang.Object)
getDeclaredMethods=>public java.lang.String com.badwei.reflection.User.toString()
getDeclaredMethods=>public int com.badwei.reflection.User.hashCode()
getDeclaredMethods=>public int com.badwei.reflection.User.getId()
getDeclaredMethods=>public int com.badwei.reflection.User.getAge()
getDeclaredMethods=>protected boolean com.badwei.reflection.User.canEqual(java.lang.Object)
getDeclaredMethods=>public void com.badwei.reflection.User.setId(int)
getDeclaredMethods=>public void com.badwei.reflection.User.setAge(int)
getDeclaredMethods=>public java.lang.String com.badwei.reflection.User.getUsername()
getDeclaredMethods=>public void com.badwei.reflection.User.setUsername(java.lang.String)
public java.lang.String com.badwei.reflection.User.getUsername()
public void com.badwei.reflection.User.setUsername(java.lang.String)
getConstructors=>public com.badwei.reflection.User()
getConstructors=>public com.badwei.reflection.User(java.lang.String,int,int)
getDeclaredConstructors=>public com.badwei.reflection.User()
getDeclaredConstructors=>public com.badwei.reflection.User(java.lang.String,int,int)
public com.badwei.reflection.User(java.lang.String,int,int)

14、通过反射调用属性方法构造器

package com.badwei.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test09 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {

        Class<User> c1 = (Class<User>) Class.forName("com.badwei.reflection.User");

        User user = c1.newInstance(); //本质调用了无参构造器,类要有一个访问权限足够的无参构造器
        System.out.println(user);

        //通过构造器创建对象
        Constructor<User> declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        User lxw = declaredConstructor.newInstance("lxw", 1, 18);
        System.out.println(lxw);

        //通过反射调用普通方法
        User user1 = c1.newInstance();

        // invoke() 激活
        //(对象, "方法的值")
        Method setUsername = c1.getDeclaredMethod("setUsername", String.class);
        setUsername.invoke(user1,"lxw_user1");
        System.out.println(user1.getUsername());

        //通过反射操作属性
        User user2 = c1.newInstance();
        Field username = c1.getDeclaredField("username");
        //不能直接操作私有属性,通过setAccessible()可以取消安全监测
        username.setAccessible(true); //取消安全监测
        username.set(user2,"lxw_user2");
        System.out.println(user2.getUsername());


    }
}

15、分析性能问题

正常创建 > 关闭安全监测反射 > 普通反射

16、通过反射获取泛型信息

package com.badwei.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 Test11 {

    public void test01(Map<String,User> map, List<User> list){
        System.out.println("test01");

    }

    public Map<String,User> test02(){
        System.out.println("test02");
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        Method method = Test11.class.getMethod("test01", Map.class, List.class);
        Type[] genericParameterTypes = method.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            System.out.println("#"+genericParameterType);
            if (genericParameterType instanceof ParameterizedType){
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }
        }

        Method method1 = Test11.class.getMethod("test02", null);
        Type genericReturnType = method1.getGenericReturnType();
        System.out.println("#"+genericReturnType);
        if (genericReturnType instanceof ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }

    }
}

输出:

#java.util.Map<java.lang.String, com.badwei.reflection.User>
class java.lang.String
class com.badwei.reflection.User
#java.util.List<com.badwei.reflection.User>
class com.badwei.reflection.User
#java.util.Map<java.lang.String, com.badwei.reflection.User>
class java.lang.String
class com.badwei.reflection.User

17、获取注解信息

package com.badwei.reflection;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.annotation.*;
import java.lang.reflect.Field;


public class Test12 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class<?> c1 = Class.forName("com.badwei.reflection.Student2");

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

        //获取注解value的值
        TableLxw annotation = c1.getAnnotation(TableLxw.class);
        String value = annotation.value();
        System.out.println(value);

        //活得类指定的注解
        Field f = c1.getDeclaredField("id");
        TableLxw annotation1 = f.getAnnotation(TableLxw.class);
        System.out.println(annotation1.value());
    }

}

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableLxw("lxwStudent2")
class Student2{
    @TableLxw("lxwId")
    private int id;
    private int age;
    private String name;

}

@Target({ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface TableLxw{ //自定义注解
    String value();
}

输出:

@com.badwei.reflection.TableLxw(value=lxwStudent2)
lxwStudent2
lxwId
0

评论区