Java自学-注解与反射(3)

Java自学-注解与反射(3)

1、类加载器

Java自学-注解与反射(3)

Java自学-注解与反射(3)

package lesson02;

/**
 * Author: Gu Jiakai
 * Date: 2021/9/2 19:22
 * FileName: Test07
 * Description:
 */
public class Test07 {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取系统类的加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

        //获取系统类加载器的父类加载器-->扩展类加载器
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);

        //获取扩展类加载器的父类加载器-->根加载器(C/c++)
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);

        //测试当前类是哪个加载器加载的
        ClassLoader classLoader = Class.forName("lesson02.Test07").getClassLoader();
        System.out.println(classLoader);

        //测试jdk内置的类是谁加载的
        ClassLoader classLoader1=Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader1);

        //如何获得系统类加载器可以加载的路径
        System.out.println(System.getProperty("java.class.path"));

        //双亲委派机制
    }
}

2、获取类的运行时结构

Java自学-注解与反射(3)

package lesson02;

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

/**
 * Author: Gu Jiakai
 * Date: 2021/9/2 19:51
 * FileName: Test08
 * Description:
 */
//获得类的信息
public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("lesson01.User");

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

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

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

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

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

        methods=c1.getDeclaredMethods();//获得本类的所有方法
        for (Method method : methods) {
            System.out.println("getDeclaredMethods:"+method);
        }

        //获得指定方法
        //重载
        System.out.println("------");
        Method getName = c1.getMethod("getName", null);
        System.out.println(getName);
        Method setName = c1.getMethod("setName", String.class);
        System.out.println(setName);

        //获得指定的构造器
        System.out.println("------");
        Constructor[] constructors = c1.getConstructors();//获得本类public方法
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

        Constructor[] declaredConstructors = c1.getDeclaredConstructors();//获得本类全部方法
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println("#"+declaredConstructor);
        }

        //获得指定的构造器
        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        System.out.println("指定的:"+declaredConstructor);
    }
}

3、动态创建对象执行

Java自学-注解与反射(3)

Java自学-注解与反射(3)

Java自学-注解与反射(3)

Java自学-注解与反射(3)

Java自学-注解与反射(3)

package lesson01;

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

/**
 * Author: Gu Jiakai
 * Date: 2021/9/2 20:18
 * FileName: Test09
 * Description:
 */
//动态的创建对象,通过反射
public class Test09 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //获得class对象
        Class c1 = Class.forName("lesson01.User");

        //构造一个对象
//        User user = (User) c1.getDeclaredConstructor().newInstance();//本质是调用了类的无参构造器
//        System.out.println(user);

        //通过构造器创建对象
//        Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
//        User user2 =(User) constructor.newInstance("*", 1, 5);
//        System.out.println(user2);

        //通过反射调用普通方法
        User user3 = (User) c1.getDeclaredConstructor().newInstance();
        //通过反射获取一个方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        //invoke :激活的意思/
        //(对象,"方法的值")
        setName.invoke(user3, "*");
        System.out.println(user3.getName());

        //通过反射操作属性
        System.out.println("--------");
        User user4 = (User) c1.getDeclaredConstructor().newInstance();
        Field name = c1.getDeclaredField("name");

        //不能直接操作私有属性,我们需要关闭程序的安全检测,属性或者方法的setAccessible(true)
        name.setAccessible(true);
        name.set(user4, "*2");
        System.out.println(user4.getName());
    }
}

4、性能对比分析

Java自学-注解与反射(3)

package lesson01;

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

/**
 * Author: Gu Jiakai
 * Date: 2021/9/2 20:45
 * FileName: Test10
 * Description:
 */
public class Test10 {
    //普通方式
    public static void test01(){
        User user1 = new User();
        long starttime=System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            user1.getName();
        }

        long endtime=System.currentTimeMillis();
        System.out.println("普通方式执行10亿次:"+(endtime-starttime)+"ms");
    }
    //反射方式
    public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user2 = new User();
        Class c1 = user2.getClass();

        Method getName = c1.getDeclaredMethod("getName", null);

        long starttime=System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user2,null);
        }

        long endtime=System.currentTimeMillis();
        System.out.println("反射方式执行10亿次:"+(endtime-starttime)+"ms");
    }
    //关闭检测
    public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user3 = new User();
        Class c1 = user3.getClass();

        Method getName = c1.getDeclaredMethod("getName", null);

        getName.setAccessible(true);
        long starttime=System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user3,null);
        }

        long endtime=System.currentTimeMillis();
        System.out.println("反射方式执行10亿次:"+(endtime-starttime)+"ms");
    }

    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
        test01();
        test02();
        test03();
    }
}

5、获取泛型信息

Java自学-注解与反射(3)

package lesson01;

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

/**
 * Author: Gu Jiakai
 * Date: 2021/9/2 20:56
 * FileName: Test11
 * Description:
 */
//通过反射获取泛型
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);
                }
            }
        }

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

Java自学-注解与反射(3)

上一篇:DAY 199 Python安装wheel文件


下一篇:JavaScript 计算a+b=?如何文本转成数值 *1