2016-08-04 6 views
0

Рассмотрим следующий фрагмент кода:Зачем использовать спецификаторы доступа при определении внутренних (нестатических вложенных) классов в Java?

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 (это мое понимание). Я видел программистов, указывающих спецификаторы перед вложенными внутренними классами. В чем смысл? Если (нестатические) внутренние классы вообще недоступны вне закрывающего класса, то почему спецификаторы (public, private, & protected) даны? Почему Java даже поддерживает спецификаторы доступа во внутренних классах?

+0

Целью является ограничение доступа и экспозиции. Например, 'private class InnerClass3' недоступен, даже если вы создаете экземпляр Deep. – c0der

+0

'Deep.InnerClass ic = new Deep.InnerClass(); // invalid', потому что 'InnerClass' не является статическим – emotionlessbananas

ответ

2

Вы можете создать экземпляр общественного нон статический внутренний класс, как это:

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 
    } 
} 

Если hellowworld2 была частная вы не могли бы это сделать. Таким образом, это не совсем бессмысленно, у вас может быть сценарий, в котором вы хотите создать экземпляр вне внешнего класса и не заботитесь о ссылке внешнего класса.

1
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 
     } 
    } 

Они становятся недействительными, потому что вы не доступ к нему правильный путь

, пожалуйста, используйте сигнатуру для доступа к внутренним классам

EDIT Если вы действительно хотите использовать private Inner Class, вы можете сделать это с помощью reflectio но не рекомендуется.