黑马程序员_java基础加强5

---------------------- android培训java培训、期待与您交流! ----------------------




8.类的加载、连接、初始化:

加载:将.class文件读入到内存,并为之创建一个java.lang.Class对象。一旦某个类被载入JVM中,同一个类就不会再被载入。在JAVA中,一个类用其全限定类名作为标识,这里指的全限定类名包括包名和类名。但在JVM中一个类用其全限定类名和一个加载类ClassLoader的实例ID作为唯一标识(命名空间)。如:包pg下的Person类MyClassLoader的实例a加载,在JVM中表示为(Person、pg、a)。

连接:把已读入虚拟机的二进制Java类数据合并到虚拟机的运行时状态中去。

      分为三步:.验证:加成被夹在的类是否有正确的内部结构,并和其他类协调一致。.  

                准备.:为类的静态属性分配内存,并设置默认初始值。

                解析:将类的二进制数据中的符号引用替换成直接引用。

初始化:主要是对静态属性进行初始化,包括两种方式:声明静态属性时指定初始值、使用    

        静态代码块初始化静态属性。

初始化时机:创建类的实例、调用某个类的静态方法、调用某个类的静态属性或为静态属性赋值、用Class.forName("类名")的方式加载类、初始化某个类的子类。通过类名.class方式加载某个类时,不会静态初始化。

9.Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader。类加载器也是Java类,因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是不是java类,这正是BootStrap。得到类加载器示例:

ClassLoader loader = ClassLoaderTest.class.getClassLoader();

//打印出当前的类加载器,及该类装载器的各级父类加载器

while(loader != null){

System.out.println(loader.getClass().getName());

loader = loader.getParent();

}

19.类加载器之间的父子关系和管辖范围图

10.类加载器的委托机制:

Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?

     首先当前线程的类加载器去加载线程中的第一个类。

     如果类A中引用了类BJava虚拟机将使用加载类A的类装载器来加载类B。 

     还可以直接调用ClassLoader.loadClass(String name)方法(name字符串没有.class后缀)来   

     指定某个类加载器去加载某个类。

每个类加载器加载类时,又先委托给其上级类加载器。

当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛 

ClassNotFoundException,不是再去找发起者类加载器的儿子,因为没有getChild方法, 

即使有,那有多个儿子,找哪一个呢?

每个ClassLoader本身只能分别加载特定位置和目录中的类,但它们可以委托其他的类装载器去加载类,这就是类加载器的委托模式。类装载器一级级委托到BootStrap类加载器,当BootStrap无法加载当前所要加载的类时,然后才一级级回退到子孙类装载器去进行真正的加载。当回退到最初的类装载器时,如果它自己也不能完成类的装载,那就应报告ClassNotFoundException异常。

11.自定义类加载器加载类:

被加载类:

package myclassloadertest;//结合(1)想想此处为什么要继承

public class BeLoadedClass extends MyClassLoaderTest{}

类加载器:

package myclassloadertest;

import java.io.ByteArrayOutputStream;

import java.io.FileInputStream;

import java.io.InputStream;

public class MyClassLoader extends ClassLoader {

    String classDir;

    public MyClassLoader(String classDir) {

this.classDir=classDir;

}

@SuppressWarnings("deprecation")

@Override

    protected Class<?> findClass(String className) {

     String classPath=classDir+"\\"+className+".class";

     ByteArrayOutputStream bao=null;

        InputStream fis=null;

     try {

 fis=new FileInputStream(classPath);

 bao=new ByteArrayOutputStream();

 int hasRead=-1;

 while((hasRead=fis.read())!=-1){

 bao.write(hasRead);

 bao.flush();

 }

 fis.close();

 bao.close();

catch (Exception e) {

e.printStackTrace();

}

byte buffer[]=bao.toByteArray();

     return this.defineClass( buffer, 0, buffer.length);

    }

}

类加载器测试:

package myclassloadertest;

public class MyClassLoaderTest {

public static void main(String[] args) throws Exception {

Class<?> myLoader=new 

                       MyClassLoader("bin\\myclassloadertest").

                       loadClass("BeLoadedClass");

MyClassLoaderTest clazz=(MyClassLoaderTest) //(1)

                        myLoader.newInstance();

System.out.println(clazz.getClass().getClassLoader()

                        .getClass().getName());

}

}

输出:myclassloadertest.MyClassLoader


---------------------- android培训java培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net/heima

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值