Java基础-私有静态内部类(private static class)

目录

      • 前言
      • 1.杜绝被别的外部类调度或实例化
      • 2.只为其依附的外部类服务

前言

在jdk源码中我们发现很多常用到的类里面都带有一个私有静态内部类,神秘的内部类一直都是让我头疼的东西,那这个“私有静态内部类”又是一个什么鬼呢?
解释前,我先给出一个熟识度高的使用案列—“IntegerCache”,这只是冰山一角,但他却是我们实际用的比较多的,但是被我们忽略的。jdk1.8中他是一个定义在Integer下的私有静态内部类:

  private static class IntegerCache {
     
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
     
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
     
                try {
     
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
     
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {
     }
    }

看起来跟正常类没区别呀,并且平常不是说—“静态内部类就是一个顶级类”吗?那这加了一个private又是怎么回事?

1.杜绝被别的外部类调度或实例化

class A{
     

    static class C{
     
        static final String high;
        static {
     
            high="这是C的high";
            System.out.println(high);
        }
    }

    private static class B {
     
        static final String high;
        static {
     
            high="这是B的high";
            System.out.println(high);
        }

        private B() {
     
            System.out.println("这是B()方法");
        }
    }

   public void c() {
     
       System.out.println(C.high);
       System.out.println(B.high);
    }
}


class E{
     
    public static void main(String[] args) {
     
       A.B b1=new A.B();  //这里是会报错的。
       A.C c1=new A.C();
       System.out.println(A.C.high);
       System.out.println(A.B.high);  //这里是会报错的。
    }
}

上面的代码会在注释处报错,因为静态内部类B被private修饰。

2.只为其依附的外部类服务

为其依附外部类,提供一个更小的,功能单一的小模块。并且这个模块是不需要实体化的,且不容许其他外部类访问。
给出一段代码:

class A{
     
    private static class B {
     
        static final String high;  //提供一个静态常量high
        static {
     
            high="这是B的high"+Math.random();;     //完成初始化功能,因为是static块,所以只会执行一次。
            System.out.println("static块:"+high);
        }

        private B() {
     
            System.out.println("这是B()方法");
        }
    }

   public void c() {
     
       System.out.println("c()方法:"+B.high);  
    }
}


class E{
     
    public static void main(String[] args) {
     
      A a_1=new A();       //这一步还不会执行私有静态内部类
      a_1.c();             //调用c()方法。
      a_1.c();
      A a_2=new A();
      a_2.c();             //调用c()方法。
    }
}

输出:

static块:这是B的high0.30008771595404693
c()方法:这是B的high0.30008771595404693
c()方法:这是B的high0.30008771595404693
c()方法:这是B的high0.30008771595404693

上面就是一个体现,就是当我们用到A时,加载A类并实例化A时,这一步还不会执行私有静态内部类,当我们调用c()方法时,因为c()方法中显示的调用了B.high,所以会触发B类的加载初始化,B这个小模版的功能就是提供一个high常量,并完成初始化,而这个high只提供给A使用,因为是static块,所以只会在第一次加载执行一次。所以就算我们后面还去重新实例化A对象,high值都不会在变。

Integer中的Integercache也是同理。只为其依附的外部类服务。

你可能感兴趣的:(java基础漫漫路,java,jdk,jvm)