Внутренний класс Java и статический вложенный класс - PullRequest
1626 голосов
/ 16 сентября 2008

В чем основное различие между внутренним классом и статическим вложенным классом в Java? Играет ли дизайн / реализация роль в выборе одного из них?

Ответы [ 25 ]

1 голос
/ 06 марта 2019

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

Давайте рассмотрим два следующих примера.

Статический класс вложенности: хорошим примером использования статических вложенных классов является шаблон компоновщика (https://dzone.com/articles/design-patterns-the-builder-pattern).

Для BankAccount мы используем статический вложенный класс, главным образом потому, что

  1. Статический экземпляр класса гнезда может быть создан перед внешним классом.

  2. В шаблоне построителя это вспомогательный класс, который используется для создания BankAccount.

  3. BankAccount.Builder связан только с BankAccount. Никакие другие классы не связаны с BankAccount.Builder. так что лучше организовать их вместе, не используя соглашение об именах.
public class BankAccount {

    private long accountNumber;
    private String owner;
    ...

    public static class Builder {

    private long accountNumber;
    private String owner;
    ...

    static public Builder(long accountNumber) {
        this.accountNumber = accountNumber;
    }

    public Builder withOwner(String owner){
        this.owner = owner;
        return this; 
    }

    ...
    public BankAccount build(){
            BankAccount account = new BankAccount(); 
            account.accountNumber = this.accountNumber;
            account.owner = this.owner;
            ...
            return account;
        }
    }
}

Внутренний класс. Обычно используются внутренние классы для определения обработчика событий. https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html

Для MyClass мы используем внутренний класс, главным образом потому что:

  1. Внутреннему классу MyAdapter необходим доступ к внешнему члену класса.

  2. В этом примере MyAdapter связан только с MyClass. Другие классы не связаны с MyAdapter. так что лучше организовать их вместе, не используя соглашение об именах

public class MyClass extends Applet {
    ...
        someObject.addMouseListener(new MyAdapter());
    ...
    class MyAdapter extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            ...// Event listener implementation goes here...
            ...// change some outer class instance property depend on the event
        }
    }
}
0 голосов
/ 10 сентября 2013

Прежде всего, нет такого класса, называемого Static class. Использование модификатора Static с внутренним классом (называемым Nested Class) говорит о том, что это статический член Outer Class, что означает, что мы можем получить к нему доступ как с другими статическими членами без какого-либо экземпляра внешнего класса. (Что является преимуществом статического изначально.)

Разница между использованием вложенного класса и обычного внутреннего класса:

OuterClass.InnerClass inner = new OuterClass().new InnerClass();

Сначала мы можем создать экземпляр Outerclass, затем мы можем получить доступ к Inner.

Но если класс является вложенным, то синтаксис:

OuterClass.InnerClass inner = new OuterClass.InnerClass();

Который использует статический синтаксис в качестве обычной реализации статического ключевого слова.

0 голосов
/ 10 октября 2017

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

    class Outter1 {

        String OutStr;

        Outter1(String str) {
            OutStr = str;
        }

        public void NonStaticMethod(String st)  {

            String temp1 = "ashish";
            final String  tempFinal1 = "ashish"; 

            //  below static attribute not permitted
            // static String tempStatic1 = "static";    

            //  below static with final attribute not permitted         
            // static final String  tempStatic1 = "ashish";  

            // synchronized keyword is not permitted below          
            class localInnerNonStatic1 {            

                synchronized    public void innerMethod(String str11) {
                    str11 = temp1 +" sharma";
                    System.out.println("innerMethod ===> "+str11);
                }

                /* 
        //  static method with final not permitted
          public static void innerStaticMethod(String str11) { 

                    str11 = temp1 +" india";
                    System.out.println("innerMethod ===> "+str11);
                }*/
            }

            // static class not permitted below
            //  static class localInnerStatic1 {   }                            

        }

        public static  void StaticMethod(String st)     {

            String temp1 = "ashish";
            final String  tempFinal1 = "ashish"; 

            // static attribute not permitted below
            //static String tempStatic1 = "static";     

            //  static with final attribute not permitted below
            // static final String  tempStatic1 = "ashish";                         

            class localInnerNonStatic1 {
                public void innerMethod(String str11) {
                    str11 = temp1 +" sharma";
                    System.out.println("innerMethod ===> "+str11);
                }

                /*
    // static method with final not permitted
    public static void innerStaticMethod(String str11) {  
                    str11 = temp1 +" india";
                    System.out.println("innerMethod ===> "+str11);
                }*/
            }

            // static class not permitted below
            //  static class localInnerStatic1 {   }    

        }

        // synchronized keyword is not permitted
        static  class inner1 {          

            static String  temp1 = "ashish";
            String  tempNonStatic = "ashish";
            // class localInner1 {

            public void innerMethod(String str11) {
                str11 = temp1 +" sharma";
                str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }

            public static void innerStaticMethod(String str11) {
                //  error in below step
                str11 = temp1 +" india";    
                //str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }
            //}
        }

        //synchronized keyword is not permitted below
        class innerNonStatic1 {             

//This is important we have to keep final with static modifier in non
// static innerclass below
            static final String  temp1 = "ashish";  
            String  tempNonStatic = "ashish";
            // class localInner1 {

            synchronized    public void innerMethod(String str11) {
                tempNonStatic = tempNonStatic +" ...";
                str11 = temp1 +" sharma";
                str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }

            /*
            //  error in below step
            public static void innerStaticMethod(String str11) {   
                            //  error in below step
                            // str11 = tempNonStatic +" india";                     
                            str11 = temp1 +" india";
                            System.out.println("innerMethod ===> "+str11);
                        }*/
                    //}
                }
    }
0 голосов
/ 12 декабря 2018

Язык программирования Java позволяет вам определять класс в другом классе. Такой класс называется вложенным классом и иллюстрируется здесь:

class OuterClass {
...
class NestedClass {
    ...
    }
}

Вложенные классы делятся на две категории: статические и нестатические. Вложенные классы, которые объявлены статическими, называются статическими вложенными классами. Нестатические вложенные классы называются внутренними классами. Мы должны помнить одну вещь: нестатические вложенные классы (внутренние классы) имеют доступ к другим членам включающего класса, даже если они объявлены закрытыми. Статические вложенные классы имеют доступ к другим членам включающего класса, только если они являются статическими. Он не может получить доступ к нестатическим членам внешнего класса. Как и в случае методов и переменных класса, статический вложенный класс связан с его внешним классом. Например, чтобы создать объект для статического вложенного класса, используйте следующий синтаксис:

OuterClass.StaticNestedClass nestedObject =
 new OuterClass.StaticNestedClass(); 

Чтобы создать экземпляр внутреннего класса, вы должны сначала создать экземпляр внешнего класса. Затем создайте внутренний объект во внешнем объекте с этим синтаксисом:

OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();

Почему мы используем вложенные классы

  1. Это способ логической группировки классов, которые используются только в одном месте.
  2. Увеличивает инкапсуляцию.
  3. Это может привести к более удобочитаемому и поддерживаемому коду.

Источник: Учебные руководства по Java ™ - Вложенные классы

0 голосов
/ 24 сентября 2016

Разница в том, что объявление вложенного класса, которое также является статическим, может создаваться вне пределов включающего класса.

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

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

...