`
JsonLiangyoujun
  • 浏览: 829862 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

类加载优先级

阅读更多
    笔者将通过本文向大家介绍一下Java中的类加载顺序,既然是一门编程语言,那么纯说理论是不行的,应该通过实践来验证理论,理论来指导实践。下面笔者就来写一个验证类加载优先级的Java demo供大家学习和参考。
/**
 * 
 * @author Liangyj
 *加载优先级:1.静态变量和静态代码块(类加载时执行,只加载一次并且常驻内存)、静态方法(只加载一次并且常驻内存,直接使用类名调用时才执行)
 *-->2.构造代码块(创建对象时执行)-->3.构造方法(创建对象时执行)-->4.普通方法(创建对象并调用时执行)
 */
public class TestJava {
	public static void main(String[] args) {
		System.out.println("我是main方法A:"+A+",B:"+B);
	}
	//构造方法
	public TestJava(){
		B = 10;
		A = 4;
		System.out.println("我是构造方法A:"+A+",B:"+B);
	}
	//构造代码块
		{
			A = 3 ;
			B = 3;
			System.out.println("我是构造代码块!A:"+A);
		}
	//静态变量
	private static int B = 1;
	
	//静态代码块
	static {
		A = 2 ;
		B = 2;
		System.out.println("我是静态代码块:"+"B:"+B);
	}
	
	//静态变量
	private static int A = 1;
}
class RunTest{
	@SuppressWarnings("static-access")
	public static void main(String[] args) {
		TestJava testJava = new TestJava();
		testJava.main(args);
	}
}

下面是控制台输出结果:
我是静态代码块:B:2
我是构造代码块!A:3
我是构造方法A:4,B:10
我是main方法A:4,B:10

偶然间笔者在网上看到有人写了关于类加载顺序的文章,并贴出了Java demo,最后得出了加载顺序的结论。但是笔者发现文章的作者写的代码并不严谨,得出的结论并不完全正确。因为光看在控制台输出的顺序,并不能完全说明Java的类加载顺序。比如,在加载优先级为同级时,加载和输出结果的顺序是根据代码的上下文顺序来决定的,这并不能说明优先级的高低。所以笔者在这里加以说明,以此做个提醒。笔者在代码中特意将优先级高的放在比它优先级低的代码后面,以此更为直观的证明它的优先级更高,而不是因为代码顺序导致。本Java demo纯属笔者原创,根据自己思路所写。为了方便大家代码阅读,笔者将RunTest类和TestJava类放在同一个.java文件中(为新手朋友稍作解释,老手无视即可)。

    年后回来有个小伙伴问了我个问题(如果你是一个细心的、爱思考的读者,相信你也会发现这个问题,但是并没有读者在笔者的博文下留言提问,笔者有点小小的失落,不知大家是浅尝辄止没有注意到,还是自己知道其中的道理,好了,言归正传),正好适合放在这里做引申:
    1.声明与赋值的关系(或顺序)
    2.初始化加载和创建对象时加载,以及方法调用时加载
先对第一点作出解释:在上面的代码中静态变量A,似乎是先被静态代码块赋值了,再声明的变量类型,为何该代码能通过编译呢?其实不然,虽然在上面我们已经得出了类的加载顺序,静态变量和静态代码块的优先级是相同的,此时根据代码顺序加载,但是变量(属性)的声明是先于赋值的,这是由类加载机制决定的,类的加载机制可参考:http://blog.csdn.net/boyupeng/article/details/47951037
再解释第二点:静态变量、静态代码块、静态方法是在类被加载时就初始化加载,但静态方法作为一个函数(方法)不会直接执行,同样需要被调用才执行,只不过不需要创建一个新的对象,因为它是先于对象存在的,而构造代码块和构造函数(方法)是在创建对象时加载,普通方法在被调用时才加载。
    另外注意:静态语句块中只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块可以赋值,但是不能访问。结合笔者给的demo,在上述代码中,静态代码块中给A赋值(A = 2)是可以编译通过的,而如果要引用变量A(例如输出语句改为打印A的值)则会报错:不能在定义字段之前引用字段(报错信息的中文翻译)。  --2017/2/3引申补充
    原文永久地址:http://jsonliangyoujun.iteye.com/blog/2348180
分享到:
评论

相关推荐

    springboot入门实例2:springboot配置文件的位置和加载优先级

    springboot入门实例2:springboot配置文件的位置和加载优先级 博客地址:https://blog.csdn.net/u010476739/article/details/98380095

    websphere6,7上修改类装载顺序为应用程序优先

    - 可以设置模块之间的类加载优先级,比如让某个模块优先加载其特有的类。 4. **保存并重新启动服务器**: - 完成配置后,记得点击“保存”按钮,并根据提示重启WebSphere应用服务器,让新的类加载策略生效。 5. ...

    类加载器和双亲委派模型加载类、类的加载优先级的详解.docx

    ### 类加载器与双亲委派模型详解 #### 类的生命周期与加载过程 类的生命周期主要包括七个阶段:加载、验证、准备、解析、初始化、使用和卸载。在这七个阶段中,验证、准备和解析统称为连接阶段。类的加载过程主要...

    Java 类在 Tomcat 中是如何加载的(过程分析)

    - **Eclipse中的类加载优先级**:在Eclipse中,`src`目录下的Java源代码会被编译并放置在`WEB-INF/classes`下,因此会优先于`WEB-INF/lib`中的jar包中的类加载。 - **类冲突**:在`CATALINA_HOME/lib`和`WEB-INF/...

    Java类加载原理解析

    这种机制避免了类的重复加载,并确保了核心类库的加载优先级高于用户自定义的类库。 在双亲委派机制下,类加载的过程大致分为以下几个步骤: 1. **加载(Loading)**:查找并读取类的二进制数据,通常从`.class`...

    weblogic类加载过程简述

    可以通过调整类加载顺序、设置类加载器优先级、使用命名空间隔离等手段来解决。 10. **类加载器调试** 为了帮助开发者调试类加载问题,WebLogic提供了详细的日志和跟踪选项,可以通过修改`weblogic.log.File`和`...

    CXF-JAXB包的处理问题

    在IDE中,通常需要确保JRE System Library位于所有其他库的前面,这样它的类加载优先级会更高,从而避免版本冲突。 以Eclipse为例,你可以按照以下步骤操作: 1. 打开你的项目,在"Project Explorer"或"Package ...

    jboss jar包snowdrop-vfs.jar和jboss-logging.jar

    3. 如果遇到特定的类加载问题,可以尝试调整JBoss的类加载策略,例如设置类加载优先级或隔离模块。 4. 对于日志系统,可以配置jboss-logging.jar以满足项目需求,例如指定日志输出级别、文件位置等。 5. 使用合适的...

    jbossAS7开发指南

    3. **类加载优先级**: JBoss AS7 中定义了一套清晰的类加载规则,确保不同级别的类加载器能够按照正确的顺序加载类。 4. **WAR 文件类加载**: 当部署 WAR 文件时,JBoss AS7 会为每个 WAR 文件创建一个模块,并根据...

    java的ClassLoader类加载器机制

    每个类加载器都有其特定的加载范围和优先级,确保了 Java 类的正确加载和使用。 类加载器的工作原理可以分为三个阶段:加载、链接和初始化。在加载阶段,类加载器会查找和加载指定的类。在链接阶段,类加载器会对...

    Jboss7快速入门手册

    3. **类加载优先级**:JBoss7中类加载遵循一定的优先级顺序,从系统依赖到本地资源,这种机制确保了正确的类加载顺序,减少了潜在的类加载问题。 4. **隐式模块依赖**:虽然模块默认是隔离的,但在某些情况下,如...

    tomcat-memcached所需jar包

    - 应用中的类加载优先级:当前Web应用的类 -> WEB-INF/classes -> WEB-INF/lib中的jar包 -> 全局共享的Common类库。 6. **测试与优化** - 集成完成后,需要进行测试以确保能正常连接和使用Memcached。 - 考虑...

    通过类加载机制动手实现Android热修复

    这涉及到类加载器的优先级控制。自定义的类加载器应当在找到匹配的类时,优先加载补丁中的类,从而实现热修复。此外,可能还需要处理静态初始化器的执行,以确保补丁类的正确初始化。 5. **异常处理与回滚**: 热...

    maven-classloader-plugin:只是针对Maven插件中的类加载问题的实验

    例如,可以指定哪些插件应该共享类加载器,或者设定特定插件的类加载优先级。这为开发者提供了更大的灵活性,解决了传统Maven类加载机制中可能出现的问题。 在"Maven-classloader-plugin-master"压缩包中,包含了源...

    02_类加载子系统.pptx

    这样可以避免类的重复加载,并保证核心类库(如java.lang包下的类)由引导类加载器加载,保证其优先级和安全性。 此外,JVM的类加载子系统还支持动态加载,即运行时根据需要加载类,增强了程序的灵活性。例如,插件...

    [转]LoaderQueue:带优先级的加载队列

    5. **任务处理**:LoaderQueue 可能使用一个内部的 `Loader` 类或者接口来实际执行加载操作,如 `load()` 方法。当一个任务完成加载后,队列会自动处理下一个任务。 6. **事件处理**:加载过程中,LoaderQueue 可能...

    Unity资源管理类加载AssetBundle

    本篇文章将深入探讨Unity中如何实现一个简单的资源管理类,使用协程加载AssetBundle,并支持优先级队列。 首先,我们需要了解AssetBundle的基本概念。AssetBundle是一个包含Unity资源(如GameObject、Script、...

    单片机中断优先级实验

    在PROTEUS仿真中,我们需要加载目标代码文件,并进行全速仿真。在仿真过程中,我们可以观察到单片机的工作过程,包括中断的触发、程序的执行、数据的显示等。我们可以通过仿真来 debug 源程序,查找错误,优化程序。...

    HTTP2优先级的测试页服务器和浏览器

    这允许浏览器根据需求为不同资源分配不同的优先级,减少了阻塞并提高了页面加载速度。优先级是通过权重和依赖关系来定义的,权重越大,优先级越高;一个流可以依赖于另一个流,这意味着依赖流会等待被依赖流完成后再...

    Android-Glide图片加载库的封装类

    封装类可能还提供了设置加载优先级的功能,允许开发者根据业务逻辑决定哪些图片应该优先加载。 7. **监听器**: `GlideUtils` 可能集成了加载和错误监听器,方便开发者获取加载状态,进行相应的反馈或异常处理。 ...

Global site tag (gtag.js) - Google Analytics