反射Reflect(Java基础篇)(一)

简介: 反射Reflect(Java基础篇)(一)

①. Java反射概述


1>.Java反射概述


  • ①. Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法


  • ②. 加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息


我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看

到类的结构,所以,我们形象的称之为:反射


微信图片_20220106121140.png

微信图片_20220106121145.png

微信图片_20220106121150.png


②. 获取Class的四种方法


2>. Class类


1.Class类的概述


程序在经过javac.exe 命令以后,会生成一个或多个字节码文件(.class结尾),接着我们用java.exe 命令对某个字节码文件进行解释运行。将某个字节码文件加载到内存中。此过程称为类的加载。加载到内存中的类,我们就称为运行时类,此运行时类,就作为Class的一个实例


2. 四种获取Class类实例[ 掌握 ]


  • ①. 调用运行时类的属性:Class<Person>clazz1=Person.class;


  • ②. 通过运行时类的对象,调用getClass()

该方法是Object类中的方法,所有的Java对象都可以调用该方法


③. 调用Class的静态方法: forName(String classPath)


④. 使用类的加载器: ClassLoader[了解 ]

    @Test
    public void fun1()throws Exception{
        //方式一:调用运行时类的属性
        //Class<Person>clazz1=Person.class;
        Class<Person>clazz1=Person.class;
        System.out.println(clazz1);//class itheima.com.Person
        //方式二:通过运行时类的对象,调用getClass()
        Person p1=new Person();
        Class clazz2 = p1.getClass();
        System.out.println(clazz2);
        //方式三: 调用Class的静态方法: forName(String classPath)
        Class clazz3=Class.forName("itheima.com.Person");
        System.out.println(clazz3);
        //方式四:使用类的加载器: ClassLoader[了解 ]
        //ClassLoader classLoader2=new ReflectionDemo1().getClass().getClassLoader();
        ClassLoader classLoader=ReflectionDemo1.class.getClassLoader();
        Class clazz4=classLoader.loadClass("itheima.com.Person");
        System.out.println(clazz4);
    }


哪些Class类并获取Class实例


1.class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类

2.interface:接口

3.[ ]:数组

4.enum:枚举

5.annotation:注解@interface

6.primitive type:基本数据类型

7.void


image.png


③. ClassLoader


3>. 类加载器的介绍


①. JVM支持两种类型的类加载器,分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)


②. 从概念上来讲,自定义类加载器一般指的是程序中由开发人员自定义的一类类加载器,但是Java虚拟机规范并没有这么定义,而是将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器


③. sum.misc.Launcher:它是一个java虚拟机的入口应用


④. 无论类加载器的类型如何划分,在程序中我们常见的类加载器始终只有3个,如下所示:


微信图片_20220106121433.png


微信图片_20220106121438.png


    @Test
    public void fun2(){
        //对于自定义类,使用系统类加载器进行加载
        ClassLoader classLoader = ReflectionDemo1.class.getClassLoader();
        System.out.println(classLoader);//jdk.internal.loader.ClassLoaders$AppClassLoader@726f3b58
        //调用系统类加载器getParent():获取扩展类加载器
        ClassLoader classLoader1 = classLoader.getParent();
        System.out.println(classLoader1);//$PlatformClassLoader@e73f9ac
        //调用扩展类加载器的getParent():无法获取引导类加载器
        //引导类加载器主要负责java的核心类库,无法加载自定义类
        ClassLoader classLoader2 = classLoader1.getParent();
        System.out.println(classLoader2);//null
    }
    @Test(使用ClassLoader加载配置文件)
    public void fun3()throws Exception{
        //此时的文件默认在当前的moudule下
/*        Properties prop=new Properties();
        FileInputStream fis=new FileInputStream("a.properties");*/
//      读取配置文件的方式二: 使用classLoader
        //配置文件默认识别为:当前mouble的src下
        ClassLoader classLoader=ReflectionDemo1.class.getClassLoader();
        InputStream is=classLoader.getResourceAsStream("a.properties");
        Properties prop=new Properties();
        prop.load(is);
        String username=prop.getProperty("username");
        System.out.println(username);
    }


微信图片_20220106121512.png


①. 启动类加载器


1.启动类加载器(引导类加载器 Bootstrap ClassLoader)


①. 这个类加载使用C/C++语言实现的,嵌套在JVM内部


②. 它用来加载Java的核心类库(JAVA_HOME/jre/lib/rt.jar、resource.jar或sum.boot.class.path路径下的内容),用于提供JVM自身需要的类


③. 并不继承自java.lang.ClassLoader,没有父加载器


④. 加载扩展类和应用程序类加载器,并指定为他们的父类加载器


⑤. 由于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类


②. 扩展类加载器(Extension ClassLoader)


2.扩展类加载器


①. Java语言编写,由sum.music.Launcher$ExtClassLoader实现


②. 派生于ClassLoader类


③.父类加载器为启动类加载器


④.从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext子目录(扩展目录)下加载类库。如果用户创建的JAR放在此目录下,也贵自动由扩展类加载器加载


③. 应用程序类加载器(系统类加载器)


3.应用程序类加载器(系统类加载器 AppClassLoader)


①. java语言编写,由sum.misc.Launcher$AppClassLoader实现


②. 派生于ClassLoader类


③. 父类加载器为扩展类加载器


④. 它负责加载环境变量classpath或系统属性java.class.path指定路径下的类库


⑤.该类加载是程序中默认的类加载器,一般来说,Java应用的类都是由它来完成加载


⑥. 通过ClassLoader#getSystemClassLoader()方法可以获取到该类加载器


相关文章
|
22天前
|
监控 Java
Java基础——反射
本文介绍了Java反射机制的基本概念和使用方法,包括`Class`类的使用、动态加载类、获取方法和成员变量信息、方法反射操作、以及通过反射了解集合泛型的本质。同时,文章还探讨了动态代理的概念及其应用,通过实例展示了如何利用动态代理实现面向切面编程(AOP),例如为方法执行添加性能监控。
|
2月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
88 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
1月前
|
Java
Java的反射
Java的反射。
26 2
|
2月前
|
存储 Java
[Java]反射
本文详细介绍了Java反射机制的基本概念、使用方法及其注意事项。首先解释了反射的定义和类加载过程,接着通过具体示例展示了如何使用反射获取和操作类的构造方法、方法和变量。文章还讨论了反射在类加载、内部类、父类成员访问等方面的特殊行为,并提供了通过反射跳过泛型检查的示例。最后,简要介绍了字面量和符号引用的概念。全文旨在帮助读者深入理解反射机制及其应用场景。
34 0
[Java]反射
|
3月前
|
安全 Java 索引
Java——反射&枚举
本文介绍了Java反射机制及其应用,包括获取Class对象、构造方法、成员变量和成员方法。反射允许在运行时动态操作类和对象,例如创建对象、调用方法和访问字段。文章详细解释了不同方法的使用方式及其注意事项,并展示了如何通过反射获取类的各种信息。此外,还介绍了枚举类型的特点和使用方法,包括枚举的构造方法及其在反射中的特殊处理。
73 9
Java——反射&枚举
|
2月前
|
安全 Java 测试技术
🌟Java零基础-反射:从入门到精通
【10月更文挑战第4天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
29 2
|
3月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
2月前
|
IDE Java 编译器
java的反射与注解
java的反射与注解
17 0
|
3月前
|
存储 安全 Java
扫盲java基础-反射(一)
扫盲java基础-反射(一)
|
3月前
|
Java
扫盲java基础-反射(二)
扫盲java基础-反射(二)