内部类的加载时机

   内部类是延时加载的,也就是说只会在第一次使用时加载。不使用就不加载,所以可以很好的实现单例模式。


package com.brouth.study.test;

public class OuterClass
{
    static{
        System.out.println("OuterClass static load.");
    }

    public OuterClass()
    {
        System.out.println("flag");
    }
    public OuterClass(String flag)
    {
        System.out.println("flag:"+flag);
    }
    
    class InnerClass
    {
        //private static String te = "";
        /*static{
            System.out.println("InnerClass static load.");
        }*/ 
        private OuterClass out = new OuterClass("inner");
    }
    static class InnerStaticClass
    {
        private static OuterClass out = new OuterClass("innerStatic");
        static{
            System.out.println("InnerStaticClass static load.");
        } 
        private static void load()
        {
            System.out.println("InnerStaticClass func load().");
        }
    }
    public static  OuterClass getInstatnce()
   {
      return OuterClass.InnerStaticClass.out;
   }
    public static void main(String[] args)
    {
        OuterClass.InnerStaticClass.load();
        OuterClass out = OuterClass.InnerStaticClass.out;
        OuterClass.InnerClass innerClass = out.new InnerClass() ;
        //OuterClass.InnerStaticClass.out.
    }
    
}


输出结果如下:

OuterClass static load.
flag:innerStatic
InnerStaticClass static load.
InnerStaticClass func load().
flag:inner

这个用例可以很清楚的看到内部类(不论是静态内部类还是非静态内部类)都是在第一次使用时才会被加载。

对于非静态内部类是不能出现静态模块(包含静态块,静态属性,静态方法等)

非静态类的使用需要依赖于外部类的对象,详见上述对象innerClass 的初始化。


该示例还实现了单例模式。关注其中的getInstatnce方法。








  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 单例模式是一种设计模式,它保证一个类仅有一个实例,并且提供一个全局访问点。通常情况下,单例模式被用来限制一个类的实例化次数,实现对象的全局唯一性,同时保证对象的唯一性不会受到多线程等因素的影响。 根据实例化时机的不同,单例模式可以分为懒汉式和饿汉式两种。 懒汉式在首次访问时才会创建实例,在多线程环境下需要考虑线程安全问题。优点是节约内存,缺点是第一次时需要实例化,反应稍慢。 饿汉式在类被时就会创建实例,不存在线程安全问题。优点是反应快,缺点是浪费内存。 此外,还有一种登记式单例模式,它是将每个实例都登记到一个簿记类中,使用唯一的标识符获取实例。 总的来说,单例模式可以提高代码复用率和系统的灵活性,但也可能造成一定的内存浪费。通过选用适当的实例化时机和线程安全处理方法,可以使单例模式更稳定和易用。 ### 回答2: 单例模式是一种常用的设计模式,用于确保一个类只有一个实例对象,并提供一个全局的访问点。 根据实例化的时机,单例模式可以分为饿汉式和懒汉式两种。 饿汉式单例模式会在类时就创建实例对象,然后在类的生命周期中一直存在。这种方式简单直接,线程安全,可以保证在任何时候都能获取到实例对象。然而,它的缺点是如果实例对象很庞大并且不需要立即使用,会导致内存浪费。而且,如果实例化过程中抛出异常,无法捕获并处理,导致整个程序崩溃。 懒汉式单例模式会在第一次使用时创建实例对象,延迟实例化。这种方式节省了内存空间,只有在需要时才会创建对象。然而,懒汉式的实现需要考虑线程安全性,因为多线程环境下可能会创建多个实例对象。常见的解决方法是使用同步锁或双重检查锁定,但这会增代码复杂性和执行效率。 除了以上两种分类,还有一些其他变种的单例模式,例如枚举单例模式和静态内部类单例模式。 枚举单例模式是Java中最简洁的实现方式,枚举类型保证了线程安全性和防止反射攻击,并且可以防止通过序列化/反序列化创建多个实例对象。 静态内部类单例模式使用静态内部类来持有单例实例,在外部类被时并不会立即实例化。在需要获取实例时,会调用内部类的静态方法获取单例,保证了线程安全性和延迟,并且不会产生内存浪费。 总结来说,饿汉式单例模式适用于实例对象较小且需要全局访问的场景,懒汉式单例模式适用于实例对象较大并且可能有延迟的场景,枚举和静态内部类单例模式是更安全和优雅的实现方式。但无论哪种方式,都应根据实际情况选择最合适的单例模式。 ### 回答3: 单例模式是一种常见的设计模式,它的主要目的是确保类只有一个实例,并提供一个全局的访问点供其他对象使用。 单例模式的分类主要有以下几种: 1. 饿汉式(Eager Initialization): 饿汉式单例模式在类时就创建实例,因此在使用之前就已经准备好了,所以不存在线程安全问题。它的优点是实现简单、线程安全,缺点是在整个应用程序启动时就创建实例,会占用一定的内存空间。 2. 懒汉式(Lazy Initialization): 懒汉式单例模式在类首次使用时才创建实例,这样可以延迟实例化,节省内存。然而,懒汉式需要考虑线程安全问题。常见的解决方法是锁(synchronized关键字)或双重检查锁(Double-Checked Locking)。优点是节省内存,缺点是在多线程环境下可能存在性能问题。 3. 静态内部类(Static Inner Class): 静态内部类单例模式将实例的创建延迟到静态内部类的时才进行,这样既实现了延迟,又保证了线程安全。优点是实现简单、线程安全,缺点是对序列化支持不够友好。 4. 枚举(Enum): 枚举单例模式可以防止通过反射或序列化创建新的实例,同时也保证了线程安全。枚举类型的成员是唯一的,因此每个枚举值都是单独的实例。优点是实现简单、线程安全,缺点是不灵活,不能延迟。 总体来说,单例模式的优点是能够确保只有一个实例存在,全局可访问,避免频繁的内存创建和销毁,提高性能。缺点是可能存在线程安全的问题,需要额外的处理。根据具体的应用场景,可以选择适合的单例模式实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值