举例讲解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"));
}
}