`

java类加载先后顺序

 
阅读更多

这里讲的不是类加载机制,是类的加载先后顺序。话不多说了,先设定以下场景:

 

package com.jingdong;

public class A {
	
	public  static  void main(String[] args){
		System.out.println(Ib.b);
			B b=new B();
			b.ibTest();
	}
}

 

public class B implements Ib{
	private D d;
	private C c=new C();
	@Override
	public void ibTest() {
		// TODO Auto-generated method stub
		System.out.println("ibtest hello1");
		d=new D();
	}
}

 

public class C implements Ic{

	@Override
	public void icTest() {
	}
	
}

 

public class D {

}

 

public interface Ib {
	public static String b="this b ";
	public void ibTest();
}

 

public interface Ic {
	public void icTest();
}

 

执行该程序:java -verbose:class com.jingdong.A

输出如下:

[Loaded com.jingdong.A from file:/F:/myj2ee/j2ee/classTest/src/]

this b 

[Loaded com.jingdong.Ib from file:/F:/myj2ee/j2ee/classTest/src/]

[Loaded com.jingdong.B from file:/F:/myj2ee/j2ee/classTest/src/]

[Loaded com.jingdong.Ic from file:/F:/myj2ee/j2ee/classTest/src/]

[Loaded com.jingdong.C from file:/F:/myj2ee/j2ee/classTest/src/]

ibtest hello1

[Loaded com.jingdong.D from file:/F:/myj2ee/j2ee/classTest/src/]

 

顺序如下:

首先JVM查找main方法,加载到A类

main方法第一句是:System.out.println(Ib.b);输出了:this b 

注意此时并没有加载Ib接口,说明:在使用接口的静态变量时是不会加载该接口口的

 

main方法第二句:B b=new B();输出了:

[Loaded com.jingdong.Ib from file:/F:/myj2ee/j2ee/classTest/src/]

[Loaded com.jingdong.B from file:/F:/myj2ee/j2ee/classTest/src/]

说明加载了B,在加载B时,会优先加载B的超类(父类)和接口.这里有个疑问,到底是表达表B b触发了加载B类还是new B()呢,后面会讲到。

 

再看后面两句输出:

[Loaded com.jingdong.Ic from file:/F:/myj2ee/j2ee/classTest/src/]

[Loaded com.jingdong.C from file:/F:/myj2ee/j2ee/classTest/src/]

该输出是由于加载B类触发的,因为B类用到了成员变量C,D,但是为什么只加载了C而没有加载D呢。看B的声明:

private D d;

private C c=new C();

这说明:

只是引用一个类时是不会类加载器去加载该类的,只有在需要实例化类或者调用XXX.class时才会去加载。这里只有C被实例化了,因此只会输出加载了Ic和C

 

最后A类的main方法执行了:b.ibTest();

输出如下:System.out.println("ibtest hello1");

然后再执行语句d=new D();的时候触发了D的加载。

 

 

现在我好奇如果我们把d=new D();去掉,在javac以后(即编译以后)是不是就可以把D.class删了呢。

经实验发现这的确是可行的,因为D类一直没有机会实例化,因此可以删除

 

3
2
分享到:
评论
2 楼 bernoulli 2013-10-15  
fncj 写道
厉害,现在在工作的过程经常会遇到因为类加载顺序导致的问题

请关注类初始化顺序
1 楼 fncj 2013-10-15  
厉害,现在在工作的过程经常会遇到因为类加载顺序导致的问题

相关推荐

    java面试题静态加载顺序构造方法

    4.知道了static的作用,那么X类被加载,那么就会先执行X类的静态属性和静态语句块(static),执行先后顺序看谁在前面就先执行谁。只在此时执行,以后都不会。 5.所以一个输出结果为tttt,没问题了吧。 6.X类的...

    Java中类加载过程全面解析

    1、先加载执行父类的静态变量及静态初始化块(执行先后顺序按排列的先后顺序) 2、再加载执行本类的静态变量及静态初始化块,只要类没有被销毁,静态变量及静态初始化块只会执行 1 次,后续再对该类进行其他操作也...

    Java初始化顺序1

    在类内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。 类变量和实例变量的区别在于:类变量是所有对象共有,其中一个对象...

    web.xml文件中配置(servlet, spring, filter, listenr)的加载顺序

    这段代码指定了一个Listener类`ContextLoaderListener`,该类由Spring框架提供,用于在应用程序启动时加载Spring的上下文配置。 #### Filter Filter是在请求到达目标资源之前可以执行预处理操作的对象,并且在响应...

    web.xml中servlet, bean, filter, listenr 加载顺序_动力节点Java学院整理

    在web.xml文件中,Filter的执行顺序是按照Filter-mapping的先后顺序进行的。如果 Filter-mapping的顺序不正确,将可能导致乱码问题的出现。例如,在web.xml文件中,如果我们配置了两个Filter,分别是SecurityFilter...

    环境变量的先后顺序对同一软件不同版本的影响

    ### 环境变量的先后顺序对同一软件不同版本的影响 #### 一、环境变量的基础概念 环境变量是在操作系统环境中定义的一系列特殊变量,用于存储有关系统配置的信息。这些变量可以由应用程序读取或直接使用,以确定...

    java中static作用

    如果 static 代码块有多个,JVM 将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。 静态变量和实例变量的区别 静态变量和实例变量是两种不同的变量类型。静态变量在内存中只有一个拷贝,...

    Java类的初始化顺序知识点总结

    在这两个部分中,静态变量和静态初始化块的初始化顺序取决于它们在类中出现的先后顺序。 实例初始化顺序为:变量 -> 初始化块 -> 构造器。同样,在这三个部分中,变量、初始化块和构造器的初始化顺序也取决于它们在...

    java中静态代码块与构造方法的执行顺序判断

    在Java编程语言中,了解静态代码块和构造方法的执行顺序是至关重要的,尤其是在处理类的初始化和对象的创建时。下面将详细解释这些概念及其执行逻辑。 首先,静态代码块(也称为静态初始化器)是由`static`关键字...

    深入理解_Java_虚拟机_(JVM_高级特性与最佳实践)

    - **有序性**:程序执行顺序按照代码的先后顺序执行。 ##### 5.2 锁优化 为了提高并发性能,JVM实现了多种锁优化机制,如轻量级锁、偏向锁和自旋锁等。这些机制在保证线程安全的同时尽可能减少锁带来的性能开销。 ...

    java中final和static的区别

    static 语句块,可以有多个,位置可以随意放,它不在任何的方法体内,JVM 加载类时会执行这些静态代码块,是该类中最先被执行的代码,如果有多个静态代码块,会按照它们在类中出现的先后顺序执行它们,每个静态代码...

    JAVA面试题解惑系列

    其顺序取决于它们在类中声明的先后顺序。例如: ```java public class TestOrder { // 静态变量 public static TestA a = new TestA(); // 静态初始化块 static { System.out.println("静态初始化块"); } ...

    JAVA面试题解惑系列.docx

    静态变量和静态初始化块的初始化顺序取决于它们在类中出现的先后顺序。例如: ```java public class TestOrder { public static TestA a = new TestA(); static { System.out.println("静态初始化块"); } ...

    java offer来了原理篇.pdf

    例如,栈和队列在处理具有先后顺序的问题时非常有用,链表适用于经常插入和删除节点的场景,而散列表和树结构则在快速查找和排序方面有着显著优势。 第五部分涉及到Java中的常用算法,包括二分查找、排序算法等。...

    Volley,FastJson,.解析网络Json,多线程显示图片。图片缓存,解决图片对不上文字,图片排序混乱问题,万能适配器

    解决图片对不上文字和排序混乱的问题,通常需要在数据模型中存储每个图片的对应信息,如图片URL和对应的文本内容,然后在适配器中按照特定的顺序进行绑定。万能适配器(BaseAdapter)可以灵活地适用于各种不同的列表...

    举例说明Java中代码块的执行顺序

    在Java编程语言中,了解类的初始化顺序是至关重要的,因为这直接影响到代码的执行逻辑。下面我们将详细探讨Java中代码块的执行顺序,包括静态属性、非静态属性、静态代码块、非静态代码块以及构造函数。 首先,让...

    java判断题整理全.doc

    20. **类加载顺序**:类加载器加载类不分先后,由需求决定。 21. **main方法**:`main`方法前的`public`和`static`是必要的,但不一定都需要。 22. **public类数量**:源文件中多个public类会导致编译错误。 23. ...

    javaLGantt_java源码中文版_java_甘特图源代码_

    通过这种方式,可以直观地看出哪些任务是并行进行的,哪些任务有先后顺序,以及项目的整体进度。 在Java中实现甘特图,通常会用到Swing或JavaFX这样的GUI库。Swing是Java的标准GUI库,提供了丰富的组件和布局管理器...

    java虚拟机总结

    - **有序性**:程序执行的顺序按照代码的先后顺序执行,但在多线程编程中,由于编译器优化等原因,可能会发生指令重排序。 6. **先行发生原则** - 一种用于解决多线程程序中发生顺序的规则,用来确保不同线程间的...

    java复习精华

    - **顺序结构**: 按照代码出现的先后顺序执行。 - **选择结构**: 根据条件选择执行不同的代码块,如 `if` 语句、`switch` 语句。 - **循环结构**: 重复执行一段代码,如 `for` 循环、`while` 循环。 - **程序转移...

Global site tag (gtag.js) - Google Analytics