(转)classload和class.forname()区别

转自:http://carl-java.iteye.com/blog/978680

java中class.forName和classLoader都可用来对类进行加载。前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。而classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象 
事例代码如下: 
1.使用classLoader加载

System.out.println("before loadClass... "); 
    Class c =Test.class.getClassLoader().loadClass("com.hundsun.test.ClassInfo"); 
    System.out.println("after loadClass... "); 
    System.out.println("before newInstance... "); 
    ClassInfo info1 =(ClassInfo) c.newInstance(); 
    System.out.println("after newInstance... ");

输出结果: 
before loadClass... 
after loadClass... 
before newInstance... 
static invoked... 
contruct invoked... 
after newInstance...

2.使用class.forName进行加载

System.out.println("before class.forName"); 
Class cc =Class.forName("com.hundsun.test.ClassInfo"); 
System.out.println("after class.forName"); 
ClassInfo info2 =(ClassInfo) cc.newInstance(); 
输出结果: 
before class.forName 
static invoked... 
after class.forName 
before newInstance... 
contruct invoked... 
after newInstance...

下面说一下两者具体的执行过程 
LoadClass()方法加载类及初始化过程: 
类加载(loadclass())(加载)——》newInstance()(链接+初始化) 
newInstance(): 
(开始连接)静态代码块——》普通变量分配准备(a=0;b=0;c=null)——》(开始初始化)普通变量赋值(a=1;b=2;c=”haha”)——》构造方法——》初始化成功。

Class.forName(Stirng className)一个参数方法加载类及初始化过程: 
类加载(Class.forName())(加载)——》静态代码块——》newInstance()(链接+初始化)

newInstance(): 
(开始连接)普通变量分配准备(a=0;b=0;c=null)——》(开始初始化)普通变量赋值(a=1;b=2;c=”haha”)——》构造方法——》初始化成功。

Class.forName()三个参数的加载类及初始化过程同classLoader一样。

从上边的断点调试可以看出,静态代码块不是在初始化阶段完成的,它陷于类初始化,先于普通变量默认分配(整型分配为0,字符串分配为null),这也就是为什么我们不能在静态代码块中引用普通变量的原因之一,这与上面所谓的“分配”、“初始化”相违背。

所以我觉得JVM的类加载及初始化过程应该是这样的。

1. 类加载:Bootstrap Loader——》Extended Loader——》System Loader 
2. 静态代码块初始化 
3. 链接: 
a) 验证:是否符合java规范 
b) 准备:默认初始值 
c) 解析:符号引用转为直接引用,解析地址 
4. 初始化 
a) 赋值:java代码中的初始值 
b) 构造:构造函数

时间: 2024-10-08 03:34:47

(转)classload和class.forname()区别的相关文章

JVM思考-ClassLoader.loadClasshe和Class.forName区别

JVM思考-ClassLoader.loadClasshe和Class.forName区别 目录:JVM总括:目录 见博客第四节:JVM总括四-类加载过程.双亲委派模型.对象实例化过程 原文地址:https://www.cnblogs.com/java-zzl/p/9905223.html

Class.forName()概述

## Class.forName解析 从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载.但是使用newInstance()方法的时候,就必须保证: - 这个类已经加载 - 这个类已经连接了 而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载 java API的那个加载器. > 现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化. -

【转】 Class.forName()用法及与new区别 详解

平时开发中我们经常会发现:用到Class.forName()方法.为什么要用呢? 下面分析一下: 主要功能Class.forName(xxx.xx.xx)返回的是一个类Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段 在初始化一个类,生成一个实例的时候,newInstance()方法和new关键字除了一个是方法,一个是关键字外,最主要有什么区别?它们的区别在于创建对象的方式不一样,前者是使用类加载机制,后者是创建一个新类.

Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别(转)

一.Java的反射机制   每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图:  其中 i.加载是指将编译后的java类文件(也就是.class文件)中的二进制数据读入内存,并将其放在运行时数据区的方法区内,然后再堆区创建一个Java.lang.Class对象,用来封装类在方法区的数据结构.即加载后最终得到的是Class对象,并且更加值得注意的是:该Java.lang.Class对象是单实例的,无论这个类创建了多少个对象,他的Class对象时唯一的!!!!.

理解java中反射,区别Class.forName(),Class.forName().instance() ,new

先了解一下反射(这玩意着实让我理解了很久啊)博文参考(http://blog.csdn.net/cookieweb/article/details/7056277) 先了解一些基本的概念:运行时,编译时,编译型,解释型,类加载器,动态加载类  什么是编译?将原程序翻译成计算机语言,就是二进制代码,在java中是将.java文件也就是源程序翻译成.class的字节码  什么是编译时?将原程序翻译成计算机语言的过程中,将.java翻译为.class文件的过程  什么是运行时?就是在启动这个程序的时候

Class.forName("ClassName")与ClassName.class的区别

引发问题的来源:最近在看比较深入的JVM相关的书,不得不感慨,JVM确实是比较深奥,很多地方难以理解不说,在网上还找不到什么资料,发现一个左思右想都想不明白的问题上网来搜索,结果基本上都是从书上copy下来的东西,还是不能理解. 问题的出现:今天突然想到一个这样的问题,就是类变量也就是静态变量的初始化问题.以前的范范理解是静态变量在类加载的时候就会初始化,反正是在初始化堆内存的之前会初始化静态变量,知道是这么一回事,但是不知其所以然.因为类加载其实也是有很多个步骤的,比如加载-连接-初始化.以前

91 Class.forName 实例对象.class,实例对象.getClass()的区别

其中 .getClass()是动态的,其余是静态的. .class和class.forName()只能返回类内field的默认值,getClass可以返回当前对象中field的最新值 Class.forName() 返回的是一个类,.newInstance() 后才创建一个对象,Class.forName()的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码块 new关键字和newInstance()方法的区别: newInstance: 弱类型.低效率.只能调用无参构造.

Class.forName().newInstance()和通过new得到对象的区别

写代码看到一条newInstance()语句,不是很理解它和new()的区别,就找了些资料,在这里总结一下.先看一个例子: package com.zz.bridge.impl; /** * Copyright 2015年6月16日 * created by txxs * all right reserved */ public class ClassDemo { /** * 构造函数 */ public ClassDemo() { System.out.println("classDemo!&

ClassLoader.loadClass和Class.forName的区别

为什么要把ClassLoader.loadClass(String name)和Class.forName(String name)进行比较呢,因为他们都能在运行时对任意一个类,都能够知道该类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性. 在比较它俩之前需先了解一下java类装载的过程 java类装载过程分为3步: 1:加载 Jvm把class文件字节码加载到内存中,并将这些静态数据装换成运行时数据区中方法区的类型数据,在运行时数据区堆中生成一个代表这个类 的java.lan