0
点赞
收藏
分享

微信扫一扫

JAVA-注解和反射二{反射机制}JAVA从基础开始 --4

江南北 2022-01-16 阅读 68

JAVA-注解和反射二{反射机制}JAVA从基础开始 --4

反射机制

+JVM 讲解 运行时候创建对象(classLoader)

java反射机制概述

Java Reflection—反射机制

Java反射机制研究及应用

优点

缺点

主要api

Class类

Class类的常用方法

方法名功能说明
static Classforname(String name)返回指定类名name的 Class对象
Object newlnstance()调用缺省构造函数,返回 Class对象的一个实例
getName()返回此Cass对象所表示的实体(类,接口,数组类或void)的名称
Class getSuperClass()返回当前Cass对象的父类的Cass对象
Class[] getinterfaces()获取当前 Class对象的接口
ClassLoader getClassLoader()返回该类的类加载器
Constructor[] getConstructors()返回一个包含某些 Constructor对象的数组
Method getMothed( String name, Class.T)返回一个 Method对象,此对象的形参类型为paramType
Field[] getDeclaredFelds()返回Feld对象的一个数组

哪些类型可以有Cas对象?

Java内存分析存放new的对象和数组堆可以被所有的线程共享,不会存放别的对象引用存放基本变量类型(会包含这个基本类型的具体数值)Java内存栈引用对象的变量(会存放这个引用在堆里面的具体地址)可以被所有的线程共享方法区包含了所有的 class和 static变量

请添加图片描述

◆初始化

# 类的初始化

什么时候会发生类初始化?类的主动引用(一定会发生类的初始化)

package main.Reflection;

//类的主动引用--类会初始化
public class Test06 {
    static {
        System.out.println("main方法被加载");
    }

    public static void main(String[] args) throws ClassNotFoundException {
//        Son son = new Son();
//反射也会产生引用
        Class.forName("main.Reflection.Son");
    }
}

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;
}

类的被动引用(不会发生类的初始化)

类加载器的作用

package main.Reflection;


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("main.Reflection.Test07").getClassLoader();
//        System.out.println(classLoader);
//       //测试jdk内置类是哪个加载器加载的
//        ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader();
//        System.out.println(classLoader1);
//
//
        //如何获得系统类加载器加载的路径
        String property = System.getProperty("java.class.path");
        System.out.println(property);
        //双委派机制
           //java.lang.String---->用户类加载器--->根加载器
          //如果手写了个java.lang.String,不会运行,而是会找到根加载器上的来用
        /**
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\charsets.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\deploy.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\access-bridge-64.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\cldrdata.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\dnsns.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jaccess.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jfxrt.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\localedata.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\nashorn.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunec.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunjce_provider.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunmscapi.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunpkcs11.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\zipfs.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\javaws.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\jce.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfr.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfxswt.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\jsse.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\management-agent.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\plugin.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\resources.jar;
         * C:\Program Files\Java\jdk1.8.0_301\jre\lib\rt.jar;
         * E:\obj\ideaObj\annotation\out\production\annotation;
         * D:\idear\IntelliJ IDEA 2021.2\lib\idea_rt.jar
         */
        
        
    }
}

创建运行时类的对象

package main.Reflection;

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

//获得类的信息
public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("main.Reflection.User");

//        User user = new User();
//        c1 = user.getClass();

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

        //获得类的属性
        System.out.println("===========类的属性=========");
        Field[] fields = c1.getFields();//只能找到public属性
//        for (Field field : fields) {
//            System.out.println(field);// 打印不出来
//        }
        fields = c1.getDeclaredFields();//找到所有属性
        for (Field field : fields) {
            System.out.println(field);
        }
        Field name = c1.getDeclaredField("name");//从全部属性中找 private name
//        Field name1 = c1.getField("name");//只能找public属性   没有public的name属性
        System.out.println(name);

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

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


    }

}

动态创建对象执行方法

	package main.Reflection;

import java.lang.reflect.Field;

//动态创建对象,通过反射
public class Test09 {

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //获得Class对象
        Class c1= Class.forName("main.Reflection.User");

        //构造一个对象
        User user = (User)c1.newInstance();//调用无参构造器
        System.out.println(user);

        System.out.println("=======================");

        User user1 = (User)c1.newInstance();//调用无参构造器
        Field name = c1.getDeclaredField("name");

        //不能直接操作私有属性,需要关闭程序的安全检测  setAccessible(true)
        name.setAccessible(true);//权限检查 使private失效,默认false不启用,true是启用
        name.set(user1,"小学生");
        System.out.println(user1.getName());

    }
}

调用指定方法

setAccessible

性能检测

package main.Reflection;

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

//分析性能问题
public class Test10 {
    //普通方式调用
    public static void test01() {
        User user = new User();

        long startTime = System.currentTimeMillis();

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

        long endTime = System.currentTimeMillis();
        System.out.println("普通方式执行getName十亿次需要的时间:" + (endTime - startTime) + "ms");
    }


    //反射方式调用
    public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);

        long startTime = System.currentTimeMillis();

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

        long endTime = System.currentTimeMillis();
        System.out.println("反射方式执行getName十亿次需要的时间:" + (endTime - startTime) + "ms");
    }

    //反射方式调用
    public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);
        getName.setAccessible(true);

        long startTime = System.currentTimeMillis();

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

        long endTime = System.currentTimeMillis();
        System.out.println("关闭检测反射方式执行getName十亿次需要的时间:" + (endTime - startTime) + "ms");
    }


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

获取泛型信息

反射操作泛型

package main.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("01");
    }

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

    public static void main(String[] args) throws NoSuchMethodException {
        Method me = Test11.class.getMethod("test01", Map.class, List.class);

        Type[] genericParameterTypes = me.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);
                }
            }
        }

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

获取注解信息

package main.Reflection;

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("main.Reflection.Student2");
        //通过反射获取注解

        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        //获得注解value的值
        TableCloud tableCloud = (TableCloud) c1.getAnnotation(TableCloud.class);
        String value = tableCloud.value();
        System.out.println(value);

        //获得类指定的注解
        Field f = c1.getDeclaredField("id");
        FieldCloud annotation = f.getAnnotation(FieldCloud.class);
        System.out.println(annotation.conlumnName());
        System.out.println(annotation.type());
        System.out.println(annotation.length());
    }


}

@TableCloud("db_student")
class Student2 {
    @FieldCloud(conlumnName = "db_id", type = "int", length = 10)
    private int id;
    @FieldCloud(conlumnName = "db_age", type = "int", length = 10)
    private int age;
    @FieldCloud(conlumnName = "db_name", type = "String", length = 3)
    private String name;

    public Student2() {
    }

    public Student2(int id, int age, String name) {
        this.id = id;
        this.age = age;
        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;
    }

    public String getName() {
        return name;
    }

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


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

//属性注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldCloud {
    String conlumnName();

    String type();

    int length();
}
举报

相关推荐

0 条评论