Почему в классе есть открытый статический класс

Я прошел через код, и я увидел это:

public class A {
    public A(SomeObject obj) {
      //Do something
    }
    //Some stuff
  public static class B {
    //Some other stuff
  }
}

Мне было интересно, потому что даже внутренний класс является public почему он является вложенным, а не отдельным классом? Кроме того, могу ли я сделать это здесь: new AB(SomeObject)? Я чувствую, что это побеждает цель статического класса, но я видел эту реализацию так, как хотелось бы знать.

Ответ 1

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

Это действительно вопрос, чтобы спросить того, кто написал класс. Это может позволить внешнему классу действовать как "мини-пространство имен", хотя, если вложенный класс полезен только в контексте внешнего класса, он кажется разумным. Это указывает на преднамеренную плотную связь между двумя классами. Я чаще всего вижу это в контексте шаблона построителя:

Foo foo = new Foo.Builder().setBar(10).build();

Здесь имеет смысл, что Foo.Builder вложен в Foo а не как одноранговый класс, который предположительно будет называться FooBuilder.

Обратите внимание, что это также дает некоторые различия в видимости по сравнению с несвязанными классами.

Кроме того, могу ли я сделать это здесь: new AB(SomeObject)?

Нет, потому что B не имеет конструктора с параметром SomeObject - только A делает (в примере, который вы SomeObject).

Я чувствую, что это побеждает цель статического класса

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

Ответ 2

У вас был бы такой внутренний класс

  • вы можете сохранить класс, который существует только для поддержки инкапсулированного внешнего класса.
  • вы хотите иметь доступ к private членам внешнего класса или другим вложенным классам.
  • вам нужен вложенный класс со статическими полями (слабая причина, о которой я знаю;)
  • у вас есть класс с очень общим именем, например Lock или Sync который вы бы не хотели смешивать с другими классами с тем же именем, которые используются классами в одном пакете.

могу ли я сделать это здесь: новый AB (SomeObject)?

Ты можешь.

Я чувствую, что это побеждает цель статического класса

Это требует привыкания, но как только вы начинаете, у вас может возникнуть проблема не превращать всю вашу программу в один файл. Java;)

Ответ 3

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

Посмотрите на эту тему: почему странное соглашение об именах "AlertDialog.Builder" вместо "AlertDialogBuilder" в Android

Кроме того, могу ли я сделать это здесь: новый AB (SomeObject)?

(Update) Нет, вы не можете этого сделать, поскольку B не имеет конструктора, который запрашивает SomeObject.

Надеюсь, это поможет.

Ответ 4

1. static inner класс известен как класс Top-Level.

2. Этот static class имеет прямой доступ к Статическому методу и переменным класса Outer .

3. Вам нужно будет инициализировать static Inner class таким образом извне...

    A a = new A();
    A.B b = new A.B();

4. new AB(SomeObject) не будет работать... потому что у вас нет конструктора с SomeObject качестве параметра...

5. Но если класс Inner нестационален, то он имеет неявную ссылку на класс Outer.

6. Внешний и внутренний класс может распространяться на разные классы.

7. interface method может быть реализован несколько раз разными или одинаковыми способами, используя Inner Class.

Ответ 5

Этот шаблон используется очень часто с шаблоном построителя. Это не только упрощает связь между классом и его создателем, но и скрывает конструктор/фабрику уродливого строителя и делает построитель более удобочитаемым. Например, если вам нужен встроенный объект, который будет иметь дополнительные и необязательные свойства.

public class AnObject {
   public static class AnObjectBuilder {

       private AnObject anObject;

       private AnObjectBuilder() {
       }

       private void newAnObjectWithMandatory(String someMandatoryField, ...) {
           anObject = new AnObject(someMandatoryField,...)
       }

       public AnObjectBuilder withSomeOptionalField(String opt) {
           ...
       }
   }

   public static AnObjectBuilder fooObject() {
        return (new AnObjectBuilder()).newAnObjectWithMandatory("foo")
   }

   public static AnObjectBuilder barObject() {
        return (new AnObjectBuilder()).newAnObjectWithMandatory("bar")
   }
}

Таким образом, клиентский код должен сначала вызвать статический метод в классе AnObjectBuilder а затем использовать необязательные методы построения:

AnObject.fooObject("foo").withSomeOptionalField("xxx").build(); без создания объекта-строителя.

Довольно читаемый :)

Ответ 6

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

Простой причиной этого является удобство упаковки.

Статический вложенный класс в Java, почему?

http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

да, вы можете сделать новый AB(SomeObject). Но вам не нужно об этом говорить, попробуйте.