写道
package com.wang;
public class TestLoad {
private static TestLoad load=new TestLoad();
public static int count1;
public static int count2=0;
private TestLoad(){
count1++;
count2++;
}
public static TestLoad getInstance(){
return load;
}
public static void main(String[] args) {
TestLoad load=TestLoad.getInstance();
System.out.println("count1="+load.count1);
System.out.println("count2="+load.count2);
}
}
大家觉得这个代码的输出是什么?
答案是:
count1=1
count2=0
写道
package com.wang;
public class TestLoad {
public static int count1;
public static int count2=0;
private static TestLoad load=new TestLoad();
private TestLoad(){
count1++;
count2++;
}
public static TestLoad getInstance(){
return load;
}
public static void main(String[] args) {
TestLoad load=TestLoad.getInstance();
System.out.println("count1="+load.count1);
System.out.println("count2="+load.count2);
}
}
这个时候输出又是什么呢?
对了,是
count1=1
count2=1
这是什么原因造成的呢?
是因为在虚拟机加载类的机制造成的,
虚拟机设计类的加载顺序是:加载、链接、初始化。
加载是指:查找并加载类的二进制数据
链接又分如下三步:
–验证:确保被加载的类的正确性
–准备:为类的静态变量分配内存,并将其初始化为默认值
–解析:把类中的符号引用转换为直接引用
初始化是指:为类的静态变量赋予正确的初始值
其中说的准备和初始化都是指的对静态变量进行的,因为此时还没有实例。
造成上面输出结果的原因,也是在准备和初始化的顺序造成的。
在上面的代码中,当类加载的时候,会先执行准备操作,这个时候count1,count2都被初始化成默认值,也就是0,同时准备static TestLoad load=new TestLoad(); 这行代码的时候,会执行
private TestLoad(){
count1++;
count2++;
}
这个构造方法,此时,count1,count2都被符成了1,1;但是当类在初始化的时候,又重新把count2设置成了用户设置的初始值,也就是count2=0,而count1并没有初始值,所以count1的值还是1
而第二种情况是,static TestLoad load=new TestLoad(); 放到了两个变量已经有初始值(也就是已经完成了初始化操作)的情况下,再执行,所以count1,count2都会是1
分享到:
相关推荐
### Tomcat启动时类加载顺序详解 #### 一、引言 Apache Tomcat是一款开源的Servlet容器,主要用于部署Java Web应用程序。它支持最新的Servlet、JSP等规范,并且以其轻量级、简单易用的特点而受到开发者的青睐。在...
### Java虚拟机类加载顺序详解 #### 一、引言 在Java开发中,了解类是如何被加载到Java虚拟机(JVM)中的至关重要。本文将详细介绍JVM中的类加载顺序及其背后的原理,帮助读者理解这一过程,并掌握如何利用类加载...
WebSphere应用服务器默认的类加载顺序是先从系统类加载器(System ClassLoader)开始,然后是扩展类加载器(Extension ClassLoader),最后是应用程序类加载器(Application ClassLoader)。这种机制可能导致应用中...
Java继承关系类加载顺序问题详解 在Java中,类加载顺序问题是开发中经常遇到的问题之一。今天,我们来详解Java中继承关系类加载顺序问题,包括类加载顺序、构造方法调用顺序、静态代码块执行顺序等。 首先,让我们...
Linux内核模块加载顺序控制是Linux操作系统中一项关键技术,它决定了内核模块按照何种顺序被加载到内核中。本文将从多个角度阐述内核模块加载顺序的控制机制,包括模块的顺序声明、内核模块加载顺序控制的原理、内核...
这是因为Tomcat默认会按照上述顺序查找类,当多个目录下存在相同或相似的类时,加载顺序决定了最终加载哪个版本的类。因此,合理配置类路径,确保正确的加载顺序,是防止此类问题的关键。 #### 结论 Tomcat的类...
可以通过调整类加载顺序、设置类加载器优先级、使用命名空间隔离等手段来解决。 10. **类加载器调试** 为了帮助开发者调试类加载问题,WebLogic提供了详细的日志和跟踪选项,可以通过修改`weblogic.log.File`和`...
这些文件会按照JAR包的类加载顺序进行加载。 3. **全局属性配置**:然后是`struts.properties`,框架会读取其中的全局配置信息。 4. **主配置文件**:之后是用户定义的`struts.xml`。这个文件通常包含对整个应用的...
先静态代码块,然后构造代码块,再是构造方法,然后方法里面的代码块按顺序执行。 子类继承父类的时候,先执行父类的静态代码块,然后子类的静态代码块,然后父类的构造代码块和构造方法,再是子类的构造代码块和...
在Tomcat中,我们可以通过配置`catalina.properties`文件和`server.xml`文件来调整类加载策略,例如设置自定义的类加载顺序或启用共享类加载器。 此外,Tomcat还支持热部署,即在不重启服务器的情况下更新Web应用的...
Java中的类加载顺序是编程面试中常见的问题,它涉及到Java虚拟机(JVM)的工作机制。下面我们将详细探讨这个问题,并基于提供的代码实例进行解析。 首先,我们了解类加载的基本顺序: 1. **静态变量和静态初始化块...
Java类加载顺序笔试题 Nicobar:Java 的动态脚本和模块加载器框架 Nicobar 是一个 Java 动态脚本框架,由强大的基于 . 脚本可以是源代码,用 JVM 兼容语言(如 Groovy)编写,也可以是编译后的字节码,以 .class ...
### 内核模块加载顺序的控制 #### 前言 在Linux内核开发中,模块之间的加载顺序是非常重要的,特别是在依赖性较强的场景下。例如,一个设备驱动可能需要依赖于另一个驱动或子系统才能正常工作。为了确保系统的稳定...
4. **类加载顺序** 当Tomcat加载类时,它遵循以下顺序: - 使用Bootstrap类加载器尝试加载。 - 使用System类加载器尝试加载。 - 使用Webapp类加载器加载`WEB-INF/classes`下的类。 - 使用Webapp类加载器加载`...
类加载机制涉及类加载顺序、类加载器的体系结构、类加载过程以及双亲委派模型等核心概念。架构师或高级开发人员必须深刻理解这些知识点,以便在进行大型互联网平台架构设计和开发时做出正确的决策。 首先,类加载指...
这时,自定义类加载器如`ParentLastClassLoader.java`可以帮助我们实现这个目标,通过改变类加载顺序,使得新的类加载器可以加载新的类而不影响旧的代码。 线程上下文类加载器(Thread Context ClassLoader)是Java...
java面试题静态加载顺序构造方法 继承与static 面试题目如下:请写出程序执行完成之后的结果。 package extend; public class X { Y y=new Y(); static{ System.out.println("tttt"); } X(){ System....
经过调试,作者发现可能是因为某个类的重写版本在服务器上的加载顺序优先于标准Hibernate库,使得服务器能够正确处理字符串类型的参数。而在本地,由于JAR加载顺序的不同,加载的可能是未做兼容处理的标准Hibernate...
了解Java中继承关系的加载顺序对于理解和优化程序性能至关重要。以下是对这个主题的详细阐述: 1. 类加载机制 Java的类加载过程分为三个主要阶段:加载、验证、准备、解析和初始化。当一个类被首次引用时(例如...