一.
(1). 饿汉式:
public class Single {
public static void main(String[] args) {
//无法创建Girl对象,所以使用Girl类的类方法
Girl girl1= Girl.getInstance();
Girl girl2= Girl.getInstance();
System.out.println(girl1);
System.out.println(girl2);
//一定返回true ,因为它们都是引用了Girl中的同一个对象
System.out.println(girl1==girl2);
}
}
class Girl
{
private String name;
//注意这是一个静态属性初始化, 所以在类加载的时候就被执行, 因此只要符合三种情况就可以被加载
private static Girl t=new Girl("小红");
//(1)将构造方法私有化
//(2)在类的内部创建一个对象
//(3)用一个static方法返回此对象
private Girl(String name)
{
this.name=name;
}
public static Girl getInstance()
{
return t;
}
@Override
public String toString() {
return "Girl{" +
"name='" + name + '\'' +
'}';
}
}
(2). 饿汉式可能会造成资源浪费,可能会发生创建了对象但没有使用的情况:
public class Single {
public static void main(String[] args) {
//举例说明资源浪费:
//此时只使用了n并没有想使用girl对象的意思,但是只要使用静态成员类就会被加载,会自动执行 private static Girl t=new Girl("小红");
System.out.println(Girl.n);
}
}
class Girl
{
private String name;
public static int n=1; //静态属性
//注意这是一个静态属性初始化, 所以在类加载的时候就被执行, 因此只要符合三种情况(因为创建不了对象,所以一般是调用静态成员时被调用)就可以被加载
//所以会发生: 只要使用了类的其中一个静态成员,这个静态属性就会被加载,因此会造成浪费(举例说明)
private static Girl t=new Girl("小红");
//(1)将构造方法私有化
//(2)在类的内部创建一个对象
//(3)用一个static方法返回此对象
private Girl(String name)
{
System.out.println("构造器被调用");
this.name=name;
}
public static Girl getInstance()
{
return t;
}
@Override
public String toString() {
return "Girl{" +
"name='" + name + '\'' +
'}';
}
}
二.
(1). 懒汉式:
public class Single1 {
public static void main(String[] args) {
Cat cat1=Cat.getInstance();
Cat cat2=Cat.getInstance();
System.out.println(cat1);
System.out.println(cat2);
System.out.println(cat1==cat2);
}
}
class Cat
{
private String name;
//区别就在于静态属性有没有初始化,饿汉式直接初始化所以类加载就会创建对象
//而懒汉式是一个静态属性,没有静态属性初始化, 所以在类被加载的时候不会执行,也就不会出现调用其他静态成员时,会直接创建对象的饿汉式行为
private static Cat cat;
//(1)依旧是私有化构造方法
//(2)在类的内部声明一个静态属性对象,而不是创建初始化
//(3)提供一个public 的static方法,可以返回一个Cat对象
private Cat(String name)
{
System.out.println("构造器被调用");
this.name=name;
}
public static Cat getInstance()
{
if(cat==null)
{
cat=new Cat("小可爱");
}
//且创建一次后不为空,所以返回的一直是同一个对象
return cat;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
}
(2). 懒汉式不会发生创建对象没有使用的情况 :
public class Single1 {
public static void main(String[] args) {
//调用n是不会调用到构造方法的 ,因为懒汉式只是声明静态属性,而没有初始化静态属性
System.out.println(Cat.n);
}
}
class Cat
{
private String name;
public static int n=100;
//区别就在于静态属性有没有初始化,饿汉式直接初始化所以类加载就会创建对象
//而懒汉式是一个静态属性,没有静态属性初始化, 所以在类被加载的时候不会执行,也就不会出现调用其他静态成员时,会直接创建对象的饿汉式行为
private static Cat cat;
//(1)依旧是私有化构造方法
//(2)在类的内部声明一个静态属性对象,而不是创建初始化
//(3)提供一个public 的static方法,可以返回一个Cat对象
private Cat(String name)
{
System.out.println("构造器被调用");
this.name=name;
}
public static Cat getInstance()
{
if(cat==null)
{
cat=new Cat("小可爱");
}
//且创建一次后不为空,所以返回的一直是同一个对象
return cat;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
}
三. 区别
1. 主要区别: 创建对象的时机不同, 饿汉式在类加载的时候就创建了对象实例, 而懒汉式是在使用的时候才创建对象实例 .
2. 饿汉式不存在线程安全问题, 懒汉式存在线程安全问题.(多线程的时候判断条件会出现问题)
3.饿汉式存在浪费资源的可能, 懒汉式是在使用时才创建,所以没有这个问题.