classLoad有关的问题

1. Foo.class  代表什么

Whenever we compile any Java file, the compiler will embed a public, static, final field named class, of the type java.lang.Class, in the emitted byte code. Since this field is public, we can access it using dotted notation

JVM类加载过程划分为装载,链接和初始化。装载和链接过程完成后,即将字节码转换为为Class对象。初始化过程会执行类中静态初始化代码,静态属性的初始化。

Foo.class会生成  Class 的对象,但它并没有进行初始化

Class.forName("com.hong.classLoader.Foo"会进行初始化,因为它调用的

Class<T> java.lang.Class.forName(String name, boolean initialize, ClassLoader loader) 

initialize为true


让ClassLoader去装载Foo.class 字节码 返回代表Foo这个类的 Class对象

System.out.println(ClassLoaderDemo.class.hashCode()); 
System.out.println(Class.forName("com.hong.ClassLoaderDemo").hashCode());

 

System.out.println(ClassLoaderDemo.class.getClassLoader()); 
System.out.println(Class.forName("com.hong.ClassLoaderDemo").getClassLoader());

 


这两个产生的 Class对象是一样的,说明只装载一次

Class里有存加载它们的ClassLoader,加载他们的ClassLoader也是同一个





2. 为什么普通的类是被 AppClassLoader加载 ?

http://www.iteye.com/topic/83978 

 -----BootStrap类加载器 加载JRE/lib 
 -----ExtClassLoader 加载 JRE/lib/ext 
 -----AppClassLoader 加载ClassPath/

 

  System.out.println(System.getProperty("sun.boot.class.path")); 
  System.out.println(System.getProperty("java.ext.dirs")); 
  System.out.println(System.getProperty("java.class.path")); 

 

3.一个相同的类被两个ClassLoader加载,有什么好处

一个Application server避免两个应用相互干扰,比如tomcat下放几个工程,tomcat启动的时候把他们启动起来用不同的ClassLoader 就不会相互干扰

JVM通过类的全限定名和类加载器来标识一个被加载的类


4.不同classloader里的类能交互吗

 if class Foo is loaded by class loader B, and Foo depends on class Baz, then class Baz must be loadable by either class loader A or B. If Baz is only visible to class loader C or D, then a ClassNotFoundException will occur


5.调用static方法要创建对象吗?

不用,但要装载类,会对Class对象进行初始化

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:


  • T is a class and an instance of T is created.
  • T is a class and a static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the reference to the field is not a compile-time constant http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5313](§15.28). References to compile-time constants must be resolved at compile time to a copy of the compile-time constant value, so uses of such a field never cause initialization

反射调用类的方法也会初始化

 

 

测试代码:

/**
 * 
 */
package com.hong.classLoader;

import java.util.Random;

/**
 * @author Administrator
 * 
 */
class Initable {

	static final int staticFinal = 47;

	static final int staticFinal2 = ClassInitialization.rand.nextInt(100);

	Initable() {
		System.out.println("Initable construct  invoke");
	}

	static {
		System.out.println(" Initable  static  invoke");
	}

}

class Initable2 {

	static int staticNoFinal = 147;

	static {

		System.out.println("Initialization Initable2");

	}

}

class Initable3 {

	static int staticNoFinal = 74;

	static {

		System.out.println("Initialization Initable3");

	}

}

public class ClassInitialization {

	public static Random rand = new Random(47);

	public static void main(String[] args) throws ClassNotFoundException {
		Class<Initable> initable = Initable.class; // 不会引起初始化
		Class<?> initable2 = Class.forName("com.hong.classLoader.Initable",
				false, ClassInitialization.class.getClassLoader());// 不会引起初始化
		System.out.println(initable.hashCode());
		System.out.println(initable2.hashCode());
		System.out.println(ClassInitialization.class.getClassLoader());// classloader
																		// 是同一个

		System.out.println("after creating Initable reference");

		System.out.println(Initable.staticFinal); // 引用编译期常量不会引起初始化

		System.out.println(Initable.staticFinal2); // 引起初始化

		System.out.println(Initable2.staticNoFinal); // 引用非编译期常量会引起初始化

		Class initable3 = Class.forName("com.hong.classLoader.Initable3"); // 默认会引起初始化

		System.out.println("after creating Initable3 reference");

		System.out.println(Initable3.staticNoFinal);// 前面已经初始化此处不用再初始化
	}
}

 

 

参考:http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html#44459

http://onjava.com/pub/a/onjava/2005/01/26/classloading.html?page=1

http://www.theserverside.com/news/1364680/Understanding-J2EE-Application-Server-ClassLoading-Architectures

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值