`
annan211
  • 浏览: 461030 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

java 类加载器与程序加载实例分析

 
阅读更多
java 类加载器 可以分为

根加载器

扩展加载器

应用加载器

用户自定义加载器(继承自 java.lang.ClassLoder)

查看一个类是被何种加载器 可以使用以下代码

  public class ClassLoder {

	public static void main(String[] args) {
		System.out.println(ClassLoder.class.getClassLoader());
	}
}
 


输出的结果为

sun.misc.Launcher$AppClassLoader@19821f

可以看出  这个类 是被应用加载器加载。


判断一个类是否会被加载,可以根据 6个条件。

首次主动使用的情形:
创建某个类的新实例时--new、反射、克隆或反序列化;
调用某个类的静态方法时;
使用某个类或接口的静态字段或对该字段赋值时(final字段除外);
调用Java的某些反射方法时
初始化某个类的子类时
在虚拟机启动时某个含有main()方法的那个启动类。
除了以上几种情形以外,所有其它使用JAVA类型的方式都是被动使用的,他们不会导致类的初始化。

看一个例子

public class LoderDemo {

	public static void main(String[] args) {
		System.out.println(GG.a);
	}
}

class GG{
	public static final int a = 10;
	static{
		System.out.println("GG...");
	}
}



这短代码会输出多少呢


答案是 10
很明显  final 修饰的常量引用并不会引起类的初始化,我们再看下面一段代码。


public class LoderDemo {

	public static void main(String[] args) {
		System.out.println(GG.a);
	}
}

class GG{
	public static  final int b = 12;
	public static final int a = 1+b;
	static{
		System.out.println("GG...");
	}
}


 会输出什么呢 

答案是  13
虽然a 是个表达式  但是,表达式里面的量都是常量,会被jvm 提前折叠
再看下面这段代码


 public class LoderDemo {

	public static void main(String[] args) {
		System.out.println(GG.a);
	}
}

class GG{
	public static   int b = 12;
	public static final int a = 1+b;
	static{
		System.out.println("GG...");
	}
}



  这次的结果却是 
 GG...
 13

 虽然a 是个被final 修饰的,但是表达式含有 b一个不确定的量,所以jvm 会初始化整个类。而且静态代码块优先被执行。
 我们再看 下面一短代码


 class TestF{
	public static TestF test = new TestF();
	public static int count1 ;
	public static int count2 = 0;

	private TestF(){
		count1++;
		count2++;
	}
	public static TestF getInstances(){
		return test;
	}
}
public class SingleTownTest {
	public static void main(String[] args) {
		TestF f = TestF.getInstances();
		System.out.println("count1="+f.count1);
		System.out.println("count2="+f.count2);
	}
}



输出的结果是什么呢

 count1=1
 count2=0


根据类的加载和初始化机制,直接在启动类里面调用其他类的静态方法,会导致初始化整个类。

根据代码执行的顺序。
TestF test 将会被赋给一个null 值,count1 count2 在第一轮赋值中都被初始化为0
new TestF(); 会调用构造函数去操作 类的两个静态成员,这个时候
count = 1 ,count2 = 1,
再往下 执行
count1 没有被再次赋值,但是count2 被赋值 为 0.
所以输出会是 1,0

我们再看下面一段代码

 class TestF{
	public static int count1 ;
	public static int count2 = 0;
	public static TestF test = new TestF();

	private TestF(){
		count1++;
		count2++;
	}
	public static TestF getInstances(){
		return test;
	}
}
public class SingleTownTest {
	public static void main(String[] args) {
		TestF f = TestF.getInstances();
		System.out.println("count1="+f.count1);
		System.out.println("count2="+f.count2);
	}
}


  你会发现仅仅是将 
public static TestF test = new TestF();
 这句代码 移动了,但输出的结果却不同了。按照上面的分析,再来看一下。

 调用 静态方法 初始化了 TestF 这个类
 
 根据执行顺序,将 count1 count2 test 分别赋值为 0,0,null。
 接着 将用户手动赋值的 0 赋值给 count2,
 new TestF()  调用构造函数 并且赋值给 test
 构造函数开始给 静态成员赋值,
 count1  count2 分别自增1,值为1
 输出。
 这就是整个过程。
 好好分析类加载器,其中的强大会直接影响到你的程序效率和正确性。
分享到:
评论

相关推荐

    Java的类加载器

    类加载器和类之间存在一对一的关系,不同的类加载器加载的同名类会被视为不同的类。这为Java的模块化和隔离提供了基础,例如,在Web应用服务器中,每个Web应用都有自己的类加载器,保证了不同应用之间的类隔离。 6...

    java class loader(JAVA类加载器)

    扩展类加载器加载`jre/lib/ext`目录下的扩展库;系统类加载器则加载应用的`CLASSPATH`指定的类。 2. **双亲委派模型** 类加载机制遵循双亲委派模型,即当一个类加载器接收到加载类的请求时,它首先会把这个请求...

    Java类加载器和类加载机制实例分析

    Java类加载器和类加载机制实例分析 Java类加载器和类加载机制是Java语言的核心机制之一,它们负责将.class文件加载到内存中,并生成对应的java.lang.Class对象。下面我们将从实例形式分析Java类加载器和类加载机制...

    JAVA 类加载机制分析

    类加载的层次结构(hierarchy)从引导类加载器开始,然后是扩展类加载器(ExtClassLoader),最后是应用程序类加载器(AppClassLoader),它们之间存在父子关系,形成一个树状结构。 了解类加载机制的细节有助于...

    JVM类加载器说明文档

    3. 单例模式的实现:在多线程环境中,如果每个线程都有自己的类加载器,可能导致单例模式失效,因为每个加载器加载的类都是独立的实例。 2. 再分析类加载 类加载的过程包括三个主要步骤:加载(Loading)、验证...

    java类加载机制

    启动类加载器使用C++编写,用于加载Java的核心库,而其他类加载器则用于加载应用程序类和其他库。在判断两个类是否相等时,必须确保这两个类是由同一个类加载器加载的,否则即使来源于同一个class文件,这两个类也被...

    JAVA类加载器分析--热部署的缺陷(有代码示例,及分析)

    例如,当修改了已加载类的代码,新的类可能无法覆盖旧的类,因为它们可能被不同加载器加载,导致JVM中存在两个版本的同一类,从而引发错误。 此外,热部署还可能导致类的缓存问题。JVM为了性能考虑,会缓存已加载的...

    Java反射动态加载实例类

    ### Java反射机制与动态加载实例类 在Java中,反射是一种强大的工具,允许程序在运行时检查和修改其结构和行为。通过反射,我们可以动态地加载类、创建对象、访问和修改字段、调用方法等。本文将深入探讨Java反射...

    译 Java类加载机制(二)

    Java提供了三种内置的类加载器:Bootstrap ClassLoader(引导类加载器)、Extension ClassLoader(扩展类加载器)和AppClassLoader(应用程序类加载器)。Bootstrap ClassLoader负责加载JDK核心库,如rt.jar;...

    java自定义类加载classloader文档,包括代码

    3. **Application Class Loader(应用程序类加载器)**:也称为系统类加载器,由`sun.misc.Launcher$AppClassLoader`实现。它负责加载用户类路径(classpath)上所指定的类库。Application Class Loader的父加载器为...

    JVM实战-JVM类加载机制案例分析

    类加载器之间遵循委托机制,即下级类加载器先请求上级类加载器加载类,如果上级无法加载,则再由下级尝试加载。 3. **类的命名空间及运行时包**:类的命名空间是指在JVM中每个类都有唯一的标识符,防止命名冲突。...

    类加载机制PPT+代码

    在实际应用中,类加载器有多种,包括Bootstrap ClassLoader(引导类加载器)、Extension ClassLoader(扩展类加载器)和AppClassLoader(应用程序类加载器)。它们按照双亲委派模型工作,即子类加载器先尝试加载类,...

    解析Java虚拟机中类的初始化及加载器的父委托机制共14页

    本文将深入探讨Java虚拟机中的类初始化以及加载器的父委托机制。 一、类的加载 类加载是JVM启动时或运行中根据需要动态加载类到内存中的过程。这个过程分为三个阶段:加载、链接和初始化。 1. 加载:JVM通过类...

    JVM(三):类加载机制(类加载过程和类加载器)1

    Java虚拟机(JVM)的类加载机制是Java应用程序运行灵活性的关键。类加载涉及多个步骤,包括加载、验证、准备、解析、初始化...通过理解加载过程和类加载器的工作原理,开发者可以更好地控制和优化Java应用程序的运行。

    Java类执行顺序详解+实例(阿里面试题)+详细讲解+流程图

    类加载器通常分为系统类加载器和自定义类加载器,系统类加载器包括Bootstrap ClassLoader(负责加载JRE核心库)、Extension ClassLoader(加载扩展库)和App ClassLoader(加载应用程序类路径下的类)。 2. **验证*...

    Java记事本程序 (Java程序设计入门实例,本人老师)

    Java中的java.awt.datatransfer包提供了Clipboard接口和Transferable接口,可以实现程序内部或者与其他应用程序之间的数据交换。 图片操作可能涉及ImageIcon类,它可以加载并显示图片。Java Swing组件如JLabel可以...

    类加载说明.pdf

    2. **安全性和隔离性增强**:增强了类加载器的安全模型,使得不同的应用程序可以在同一个JVM实例中安全地共存。 3. **类加载器层次结构调整**:对类加载器的层次结构进行了调整,以适应新的模块化需求。 #### 六、...

    java源码包---java 源码 大量 实例

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    实例分析JVM安全体系双亲委派命名空间保护域策略Java开

    这样,系统类(位于JDK的rt.jar中)通常由启动类加载器加载,而用户自定义的类则由应用程序类加载器加载,保证了核心类库与用户代码的隔离。 接着,我们来看看“命名空间保护域策略”。在Java中,每个类都有自己的...

    深入Java虚拟机JVM类加载学习笔记

    - **扩展类加载器(Extension ClassLoader)**:该类加载器负责加载`<JAVA_HOME>/lib/ext`目录下的类库,或者被`java.ext.dirs`系统变量所指定的路径中的所有类库。 - **应用类加载器(Application ClassLoader)**:也...

Global site tag (gtag.js) - Google Analytics