举例讲解Java的内部类与类的加载器
内部类
classA{ //Inner1要在A初始化后才能使用,即要被A的对象所调用 classInner1{ intk=0; //staticintj=0;//A加载后,Inner1没有加载,所以这个静态变量j无法立即使用,报错 finalintz=0; /*staticvoidsay1(){ }*/ voidsay2(){ } } //Inner2在A加载好后就可以使用了 staticclassInner2{ intk=0; staticintj=0; finalintz=0; staticvoidsay1(){ } voidsay2(){ } } //调用内部类 voidc(){ finalintx=0;//final修饰后,可以由局部内部类调用 newA().newInner1();//非静态内部类Inner1,需要它所属的类的对象调用 newA().newInner1().say2(); A.Inner2.say1(); newA.Inner2().say2();//非静态方法say2(),需要它所属的类的对象调用 classInner3{ voidprint(){ System.out.println(x); } } /* *方法中的局部内部类的调用,需要在声明后因为, *在方法里的执行顺序是从上往下,而这个类 *就相当于一个局部变量当然要先声明,再使用 */ newInner3().print(); } }
类的加载器java.lang.ClassLoader
java.lang.ClassLoader类的基本职责就是根据一个指定的类的名称,找到或者生成其对应的字节代码,然后从这些字节代码中定义出一个Java类,即java.lang.Class类的一个实例。除此之外,ClassLoader还负责加载Java应用所需的资源,如图像文件和配置文件等。不过本文只讨论其加载类的功能。为了完成加载类的这个职责,ClassLoader提供了一系列的方法:
getParent() 返回该类加载器的父类加载器。
loadClass(Stringname) 加载名称为name的类,返回的结果是java.lang.Class类的实例。
findClass(Stringname) 查找名称为name的类,返回的结果是java.lang.Class类的实例。
findLoadedClass(Stringname) 查找名称为name的已经被加载过的类,返回的结果是java.lang.Class类的实例。
defineClass(Stringname,byte[]b,intoff,intlen) 把字节数组b中的内容转换成Java类,返回的结果是java.lang.Class类的实例。这个方法被声明为final的。
resolveClass(Class<?>c) 链接指定的Java类。
publicclassClassLoaderTestextendsClassLoader{ publicstaticvoidmain(String[]args)throwsSecurityException,NoSuchMethodException{ //根类加载器,加载的核心类库 URL[]urls=sun.misc.Launcher.getBootstrapClassPath().getURLs(); for(URLu:urls){ System.out.println(u); } //扩展类加载器,,加载的系统属性:java.ext.dirs返回的路径下的class System.err.println("扩展类(extentionclassLoader)加载器" +ClassLoader.getSystemClassLoader().getParent());//非继承关系,只是意义上 System.out.println(System.getProperty("java.ext.dirs")); //应用(系统applicationclassLoader)类加载器,,加载系统环境变量PATH或CLASSPATH //指定的JAR包和类路径 System.err.println("应用(系统)类加载器"+ClassLoader.getSystemClassLoader()); //System.out.println(System.getenv("PATH")); //System.out.println(System.getenv("CLASSPATH")); } }