JAVA中的类
类什么时候被初始化
主动引用类一定会初始化
当虚拟机启动,先初始化main方法所在的类 new一个类的对象 调用类的静态成员(除了final常量)和方法 使用java.lang.reflection包的方法对类进行反射 当初始化一个类,如果其父类没有被初始化,则先初始化其父类
被动引用 不会发生类的初始化
当访问一个静态域时,只有真正声明这个域的类才会被初始化 通过数组定义类引用,不会触发此类的初始化 引用常量不会触发此类的初始化
public class Reflection5 {
public static void main ( String[ ] args) throws ClassNotFoundException {
System. out. println ( "Main类被加载" ) ;
}
}
class Father {
static int b= 10 ;
static {
System. out. println ( "父类被加载" ) ;
}
}
class Son extends Father {
static int a= 100 ;
static {
System. out. println ( "子类被加载" ) ;
a= 300 ;
}
static final int M= 1 ;
}
类是怎么被加载的
三个过程:类的加载(Load) 将类的Class文件读入内存并创建一个java.lang.Class对象.有加载器构成 类的链接(Link) 将类的二进制合并到JRE中 类的初始化(Initialize) JVM负责对类进行初始化
JAVA内存分为三个部分
堆:存放new的对象和数组,可以被所以的线程共享,不会存放别的对象引用 栈:存放基本变量类型(会包含这个基本类型的具体数值),引用对象的变量(存放 这个引用在堆里的地址) 方法区:可以被所以线程共享,包含了所有的class和static变量
@SuppressWarnings ( "all" )
public class Reflection4 {
public static void main ( String[ ] args) {
A a= new A ( ) ;
System. out. println ( A. m) ;
}
}
class A {
static {
m= 300 ;
System. out. println ( "A类静态代码初始化" ) ;
}
static int m= 100 ;
public A ( ) {
System. out. println ( "A类无参构造初始化" ) ;
}
}
类加载的作用
类加载的作用:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行是数结构,然后在堆中生成一个代表这个类的clas.lang.Class对象,作为这个方法中数据的访问接口 类缓存:标准的JAVASE类加载器可以按要求查找类,一旦某个类被加载到类加载器,他将维持加载一段时间(缓存)。JVM垃圾回收机制可以回收这些Class对象 JVM规范中定义了一下类型的类的加载器 引导类加载器:由c++编写,是JVM自带的加载器,负责JAVA平台核心库,依赖加载核心内类库,加载器无法直接获得 扩展类加载器:负责Jre/lib/ext目录表下的jar包或-D java.ext.dirs指点目录下的jar包装入工作库 系统类加载器:负责java-classpath或-D java.ext.path所指的目录下类与jar包装入工作,是常用的加载器
public class Reflection6 {
public static void main ( String[ ] args) throws ClassNotFoundException {
ClassLoader classLoader= ClassLoader. getSystemClassLoader ( ) ;
System. out. println ( classLoader) ;
ClassLoader classLoader2= classLoader. getParent ( ) ;
System. out. println ( classLoader2) ;
ClassLoader classLoader3= classLoader2. getParent ( ) ;
System. out. println ( classLoader3) ;
ClassLoader classLoader4= Class. forName ( "reflection.Reflection6" ) . getClassLoader ( ) ;
System. out. println ( classLoader4) ;
classLoader4= Class. forName ( "java.lang.Object" ) . getClassLoader ( ) ;
System. out. println ( classLoader4) ;
System. out. println ( System. getProperty ( "java.class.path" ) ) ;
}
}