package com.classDownload;
class Singleton{
private static Singleton singleton=new Singleton();
public static int count1;
public static int count2=0;
private Singleton(){
count1++;
count2++;
}
public static Singleton getInstance(){
return singleton;
}
}
public class ClassDownLoad1Test {
public static void main(String [] args){
Singleton singleton=Singleton.getInstance();
System.out.println("count1="+singleton.count1);
System.out.println("count2="+singleton.count2);
}
}
count1=1
count2=0
再看下面一段代码
package com.classDownload;
class Singleton{
public static int count1;
public static int count2=0;
private static Singleton singleton=new Singleton();
private Singleton(){
count1++;
count2++;
}
public static Singleton getInstance(){
return singleton;
}
}
public class ClassDownLoad1Test {
public static void main(String [] args){
Singleton singleton=Singleton.getInstance();
System.out.println("count1="+singleton.count1);
System.out.println("count2="+singleton.count2);
}
}
结果:
count1=1
count2=1
说明:当我们运行程序时,代码会调用java虚拟机(JVM)进程,当程序运行结束时,JVM进程也将会停止
导致虚拟机停止运行得条件:
1.执行System.exit();这是我们手动得停止
2.程序执行完
3.程序抛出异常
4.操作系统自身原因
好了,正式开始说类加载器
1.类的加载,连接,初始化
加载:查找并加载二进制数据,从哪里找呢,我们编译.java文件时候,会生成.class文件,虚拟机会从我们生成得.class文件中查找,找到之后并加载到内存里面。
连接:
(1)验证:验证.class文件得正常性
(2)准备:为类得静态变量分配内存,并初始化值默认值,此时我们得实例变量都不会分配内存,只有当我们new一个实例对象才会分配内存,这就是静态变量和实例变量的区别。
(3)解析:把类中的符号引用转化为直接引用
初始化:为类得静态变量赋予正确的初始值,这里得初始化正确值和准备阶段得初始化默认值是有区别的,比如int 默认值是0,我们初始化为3,那么准备阶段的值为0,初始化阶段为3
2.java程序对类的使用方式可分为两种(所有java虚拟机实现必须在每个类或者接口被java程序首次使用时才初始化他们)
主动使用:(一共六种)
(1)创建类的实例,new一个对象
(2)访问类或者接口的静态变量,或者对静态变量赋值
(3)调用类的静态方法
(4)反射,如Class.forName();
( 5 )初始化一个类的子类
(6)java虚拟机启动时被标注为启动类的类
被动使用:其余全部是被动使用