【问题标题】:Why use access specifiers when defining inner (non-static nested) classes in Java?为什么在 Java 中定义内部(非静态嵌套)类时使用访问说明符?
【发布时间】:2016-12-10 00:59:14
【问题描述】:

考虑以下 sn-p:

class Deep {

    static class StaticInner {

    }

    class InnerClass {

    }

    public class InnerClass2 {

    }

    private class InnerClass3 {

    }

    protected class InnerClass4 {

    }
}

public class Test {

    public static void main(String args[]) {
        Deep.StaticInner sc = new Deep.StaticInner(); // valid
        Deep.InnerClass ic = new Deep.InnerClass(); // invalid
        Deep.InnerClass2 ic2 = new Deep.InnerClass2(); // invlaid
        Deep.InnerClass3 ic3 = new Deep.InnerClass3(); // invalid
        Deep.InnerClass4 ic4 = new Deep.InnerClass4(); // invalid
    }
}

除了 Deep 中名为 StaticInner 的静态类之外,所有其他嵌套类都需要封闭类 Deep 才能访问。换句话说,它们不能在Deep 之外访问(这是我的理解)。我见过程序员在嵌套内部类之前指定说明符。重点是什么?如果(非静态)内部类在封闭类之外根本无法访问,为什么要给出说明符(publicprivate、&protected)?为什么 Java 甚至支持内部类的访问说明符?

【问题讨论】:

  • 重点是限制访问和曝光。例如 private class InnerClass3 即使创建 Deep 实例也无法访问。
  • Deep.InnerClass ic = new Deep.InnerClass(); // invalid 因为InnerClass 不是静态的

标签: java inner-classes access-specifier


【解决方案1】:

您可以像这样实例化公共非静态内部类:

public class HelloWorld{

    public class HellowWorld2{
        public HellowWorld2(){
            System.out.println("Hellow World2");
        }
    }

     public static void main(String []args){
        System.out.println("Hello World");
        new HelloWorld().new HellowWorld2(); //The instantiation
     }
}

如果 helloworld2 是私有的,你就不可能做到这一点。所以它不是完全没有意义的,你可能会遇到一些你想在外部类之外实例化而不关心外部类引用的场景。

【讨论】:

    【解决方案2】:
     public class Deep {
        static class StaticInner {
    
        }
    
        class InnerClass {
    
        }
    
        public class InnerClass2 {
    
        }
    
        private class InnerClass3 {
    
        }
    
        protected class InnerClass4 {
            Deep.InnerClass3 object = new Deep().new InnerClass3(); // valid
        }
    } 
    

    ```````

    public class Test {
            public static void main(String args[]) {
                Deep deep = new Deep();
                Deep.StaticInner sc = new Deep.StaticInner(); // valid
                Deep.InnerClass ic = deep.new InnerClass(); // valid when in same package
                Deep.InnerClass2 ic2 = deep.new InnerClass2(); // vlaid
                // Deep.InnerClass3 ic3 = new Deep.InnerClass3(); // invalid because InnerClass3 is private
    
                Deep.InnerClass4 ic4 = deep.new InnerClass4(); // valid
            }
        }
    

    它们变得无效,因为您没有以正确的方式访问它

    请使用权限签名访问内部类

    编辑如果你真的想使用private Inner Class,你可以通过反射来实现,但不推荐。

    【讨论】:

      猜你喜欢
      • 2020-12-05
      • 1970-01-01
      • 1970-01-01
      • 2013-12-14
      • 2010-09-20
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      相关资源
      最近更新 更多