Java反射、类加载、初始化

简介: Class.getResource(String path) 与 Class.getClassLoader.getResource (String path) 区别:

Java反射、类加载、初始化

一、 先了解一下基本知识:

1.      字节码和机器码是什么,有什么联系

二、反射、类加载器、初始化

2.      反射:

2.1,反射理解:

2.2Class类常用方法:

2.3获取某个类的class 实例四种方法:

2.4反射优点、缺点:

2.5,反射在实际开发中的使用场景:

 

3,类加载ClassLoader:

3.1,类加载器的一个主要方法:getResourceAsStream(String str): 获取类路径下的指定文件的输入流

3.2 类加载器和inputStream 加载配置文件的区别:

3.3 配置文件的路径问题:

3.4  Class.getResource(String path) 与 Class.getClassLoader.getResource (String path) 区别:

 

4,类的加载机制

4.1 类的加载:

4.2类加载的时机

4.3 类加载器分类:

4.4 类加载的双亲委派模型

 


一、 先了解一下基本知识:


1.      字节码和机器码是什么,有什么联系

机器码:顾名思义,机器可以读懂的码;就是0、1啦;原生码(Native Code),是电脑的CPU可直接解读的数据

字节码:字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码的中间代码。(ps:OP (操作码operation code))

举例:java bytecode; 首先通过java语言编译器编写代码,生成.java 文件,然后编译器实行javac 指令,生成.class 文件(字节码文件),然后jvm 跨平台,在直译器的翻译下生成机器码,让CPU 解读。(ps:编译器的作用:编译器里我们通过高级java 高级语言,编写代码,理由编译器自带的javac 命令,生成字节码.class 文件,然后再通过编译器的java 命令,运行代码,查看结果。)

联系:字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。

 

二、反射、类加载器、初始化


2.      反射:

2.1,反射理解:照镜子

对象通过反射可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。一个 Class 对象包含了特定某个结构(class/interface/enum/annotation/primitive type/void/[])的有关信息。

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

 

在Object类中定义了public final Class getClass()方法,方法返回值的类型是一个Class类。

Class类是Reflection的根源,针对任何你想动态加载、运行的类,唯有先获得相应的Class对象。

2.2Class类常用方法:


0.png


2.3获取某个类的class 实例四种方法:


法1:  // 已知具体的类,调用运行时类的属性:.class;它主要应用于原始数据类型,并且仅在我们知道类的名称时才使用。要创建的Class对象的类名在编译时确定。         Class<?> clazz = String.class;  
法2: //已知某个类的实例,调用该实例的getClass()方法获取Class对象
    String str = new String("string");
    Class c3 = str.getClass();
法3:调用Class的静态方法:forName(String classPath)
    Class<?> clazz = Class.forName(“某个类的类名(路径)”);
法4:方式四:使用类的加载器:ClassLoader
   ClassLoader classLoader = ReflectionTest.class.getClassLoader();
   Class<?> clazz4 = classLoader.loadClass("reflection_mechanism.Person");


2.4反射优点、缺点:

优点:提高了程序的灵活性和扩展性,降低模块的耦合性;例如通过反射机制可以让程序创建和控制任何类的对象,无需提前硬编码目标类;反射是框架的灵魂,使用反射可以避免将代码写死在框架中。

缺点:性能问题:反射相当于一系列解释操作,通知jvm要做的事情,性能比直接的java代码要慢很多。把本来应该在项目启动阶段做的事情,延迟到了项目运行阶段来做。这样就增加了项目运行阶段的系统开销。安全限制:使用反射技术要求程序必须在一个没有安全限制的环境中运行。因为有内部的暴露。

2.5,反射在实际开发中的使用场景:

♢反射使用不好,对性能影响比较,一般项目中很少直接使用,主要用在底层框架中。使用反射机制,①模块开发,通过反射调用对应字节码;②动态代理模式;③spring框架、Hibernate框架等;

反射是框架设计的灵魂。

举例:

  • ① 用 IoC 来注入和组装 bean;
  • ②工厂模式:Factory类中用反射的话,添加了一个新的类之后,就不需要再修改工厂类Factory
  • ③数据库JDBC中通过Class.forName(Driver).来获得数据库连接驱动;
  • ④动态代理、面向切面、bean 对象中的方法替换与增强,也使用了反射;
  • ⑤定义的注解,也是通过反射查找

ps:什么是IoC?--- “控制反转”, 获的对象的过程被反转了,依赖注入。 控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是有外部容器的创建和维护。例如将对象的依赖交给配置文件来配置

 

3,类加载ClassLoader:

3.1,类加载器的一个主要方法:getResourceAsStream(String str): 获取类路径下的指定文件的输入流

3.2 类加载器和inputStream 加载配置文件的区别:

类加载器作用:

加载“.classpath”的资源文件,例如xml、properities文件。注意:该方式只能读取类路径(.classpath)的配置文件

InputStream 读取配置文件:

注:该方式的优点在于可以读取任意路径下的配置文件

3.3 配置文件的路径问题:

类加载器作用:加载“.classpath”的资源文件,例如xml、properities文件

注意:该方式只能读取类路径(.classpath)的配置文件

ps:查看eclipse中的.classpath 文件:Window-》show View-》Navigator(Deprecated)


1.png


  配置文件的路径是个疑惑!!!,从使用相对路径时频繁报错!!!,其实Class.getClassLoader.getResource (String path) 默认是从.classpath根下获取。


2.png3.png


//PolymorphicFunction这一行的完整代码 pro.load(HeroFactories.class.getClassLoader().getResourceAsStream("PolymorphicFunction/Pro.properties"));


3.4  Class.getResource(String path) 与 Class.getClassLoader.getResource (String path) 区别:

Class.getResource(String path)

path不以'/'开头时,默认是从此类所在的包下取资源;

path'/'开头时,则是从项目的ClassPath根下获取资源

class.getResource("/") == class.getClassLoader().getResource("")

Class.getClassLoader.getResource (String path)

♢默认是从ClassPath根下获取,path不能以’/'开头,根是src(bin),classPath文件到配置文件xml或者properties文件;

path不能以'/'开头path是指类加载器的加载范围,在资源加载的过程中,使用的逐级向上委托的形式加载的,'/'表示Boot ClassLoader,类加载器中的加载范围,因为这个类加载器是C++实现的,所以加载范围为null。

4,类的加载机制

4.1 类的加载:

  类的加载:指的是将类的.class字节码文件中的二进制数据读入到jvm内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class对象,用来封装类在方法区内的数据结构。


4.png


4.2类加载的时机:

类从被加载到虚拟机内存中开始,到卸载出内存为止,整个生命周期包括以下7个阶段:加载、验证、准备、解析、初始化、使用、卸载。

 其中验证、准备、解析3个部分统称为连接。 因此生命周期可以简记为:加载、连接(验、准、解)、初始化、使用、卸载(加连初使卸)


5.png

4.3 类加载器分类:

加载器主要有四种:

①   jvm启动类加载器bootstrap loader,用c++实现为jvm的一部分(仅指sun的hotspot),负责 JAVA_HOME/lib下面的类库中的类的加载,这个加载器,java程序无法引用到。

②   扩展类加载器Extension Loader,由sun.misc.Launcher$ExtClassLoader类实现,可在java中使用,负责JAVA_HOME/lib/ext 目录和java.ext.dir目录中类库的类的加载。

③   应用系统类加载器Application System Loader,由sun.misc.Louncher$AppClassLoader实现,负责加载用户类路径中类库中的类,如果没有使用自定义的加载器,这个就是默认的 加载器!

④   用户自定义加载器 自己定义从哪里加载类的二进制流。

4.4 类加载的双亲委派模型:

各个加载器都是先委托自己的父加载器加载类,若确实没加载到再自己来加载,于是java默认的类查找加载顺序是自顶向下的,树状结构。


6.png




目录
相关文章
|
13天前
|
安全 Java 索引
Java——反射&枚举
本文介绍了Java反射机制及其应用,包括获取Class对象、构造方法、成员变量和成员方法。反射允许在运行时动态操作类和对象,例如创建对象、调用方法和访问字段。文章详细解释了不同方法的使用方式及其注意事项,并展示了如何通过反射获取类的各种信息。此外,还介绍了枚举类型的特点和使用方法,包括枚举的构造方法及其在反射中的特殊处理。
37 9
Java——反射&枚举
|
19天前
|
安全 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版)
|
4天前
|
存储 算法 Java
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
14 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
|
25天前
|
Java 程序员 编译器
Java的反射技术reflect
Java的反射技术允许程序在运行时动态加载和操作类,基于字节码文件构建中间语言代码,进而生成机器码在JVM上执行,实现了“一次编译,到处运行”。此技术虽需更多运行时间,但广泛应用于Spring框架的持续集成、动态配置及三大特性(IOC、DI、AOP)中,支持企业级应用的迭代升级和灵活配置管理,适用于集群部署与数据同步场景。
|
9天前
|
存储 安全 Java
扫盲java基础-反射(一)
扫盲java基础-反射(一)
|
9天前
|
Java
扫盲java基础-反射(二)
扫盲java基础-反射(二)
|
2月前
|
安全 Java 关系型数据库
Java连接Mysql SSL初始化失败
Java连接Mysql SSL初始化失败
|
2月前
|
存储 Java
如何在 Java 中初始化二维 ArrayList
【8月更文挑战第23天】
58 1
|
2月前
|
存储 JavaScript Java
Java中未被初始化的字符串打印出“null”?
在Java中,未初始化的`String`变量默认值为`null`。打印此类变量时输出“null”,是因为`PrintStream`类中的`print`方法特别处理了`null`值,将其转换为字符串“null”。从JDK 17开始,`println`方法通过`String.valueOf`间接实现相同功能。当拼接包含`null`的字符串时,如`s1 + &quot;BLACK&quot;`,结果为“nullBLACK”,这是因为字符串构建过程中`StringBuilder`的`append`方法将`null`转换为“null”。
|
2月前
|
存储 Java 编译器
如何在 Java 中初始化对象 Arraylist?
【8月更文挑战第23天】
62 0
下一篇
无影云桌面