🔥Внутренние классы в Java, о которых вы не знали

Java

предисловие

Текст был включен в мой репозиторий GitHub, добро пожаловать, звезда:GitHub.com/bin39232820…
Лучшее время посадить дерево было десять лет назад, затем сейчас
Я знаю, что многие люди не играютqqТеперь, но с ностальгией, добро пожаловать в группу Six Meridian Excalibur по изучению Java для новичков, номер группового чата:549684836Поощряйте всех вести блог на пути к технологиям

болтовня

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

определение

Определение класса может быть помещено внутри другого класса, который является внутренним классом.Понятие так называемого внутреннего класса появляется только на этапе компиляции, и для слоя jvm нет понятия внутреннего класса. Мы можем использовать внутренние классы для решения

  • Проблема одиночного наследования классов, класс, который не может быть унаследован внешним классом, может быть передан внутреннему классу для наследования
  • Мы можем понять, что класс принадлежит классу в частном порядке, определив внутренний класс для достижения лучшей инкапсуляции.
  • Оптимизация кода: требуется меньше кода

Классификация

Внутренние классы можно разделить на:

  • Статический внутренний класс.
  • Нестатический внутренний класс.

Нестатические внутренние классы можно разделить на:

  • Член внутреннего класса.
  • внутренний класс метода.
  • Анонимный внутренний класс.

статический внутренний класс

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

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

public class Out {
    private static String name;
    private int age;

    public static class In{
        private int age;
        public void sayHello(){
            
            System.out.println("my name is : "+name);
            //--编译报错---
            //System.out.println("my age is :"+ age);
        }
    }
}

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

public static void main(String [] args){
    Out.In innerClass = new Out.In();
    innerClass.sayHello();
}

Сценарии использования, в общем, для ситуаций, которые тесно связаны с внешними классами, но не зависят от экземпляров внешних классов, вы можете рассмотреть возможность определения статических внутренних классов. Давайте посмотрим на несколько более сложный внутренний класс-член.

внутренний класс-член

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

public class Out {
    private String name;

    public void showName(){
        System.out.println("my name is : "+name);
    }

    public class In{
        public void sayHello(){
            System.out.println(name);
            Out.this.showName();
        }
    }
}

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

public static void main(String [] args){
    Out out = new Out();
    out.setName("六脉神剑")
    Out.In in = out.new In();
    in.sayHello();
}

Поскольку внутренний класс члена связан с конкретным экземпляром внешнего класса, создание его экземпляра должно быть создано экземпляром внешнего класса. Для создания экземпляра нам нужно только помнить, что создание экземпляра внутреннего класса-члена должно связать объект экземпляра внешнего класса, а создание экземпляра статического внутреннего класса относительно просто. Ниже мы в основном рассмотрим, как компилятор обеспечивает доступность внутреннего класса для информации о членах внешнего класса на этапе компиляции.

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

внутренний класс метода

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

public class Out {
    private String name;

    public void sayHello(){
        class In{
            public void showName(){
                System.out.println("my name is : "+name);
            }
        }

        In in = new In();
        in.showName();
    }
}

Мы определяем класс, и в этом классе определяем метод sayHello, но в этом методе мы определяем внутренний класс, класс In является внутренним классом метода. Время жизни нашего внутреннего класса метода не превышает время жизни метода, который его содержит, то есть внутренний класс метода может использоваться только внутри метода. Таким образом, во время объявления любой модификатор доступа не имеет смысла, поэтому Java просто не позволяет никакому модификатору доступа изменять внутренний класс метода. Следует также отметить, что существуют две разные вещи при определении и использовании. Не смотрите на большую строку кода, которая определяет класс. Если вы действительно хотите использовать класс, вы должны создать новый объект. класса метода, вы можете использовать его только внутри нового объекта метода. Это краткое введение во внутренний класс метода, давайте рассмотрим принцип его реализации.

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

Нет сомнений в том, что инкапсуляция внутреннего класса метода более совершенна, чем два ранее введенных. Следовательно, класс обычно определяется как метод внутреннего класса только тогда, когда требуется высокая степень инкапсуляции.

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

Пожалуй, среди всех классификаций внутренних классов имя анонимного внутреннего класса является самым большим, а также наиболее часто используемым, что чаще встречается в функциональном программировании, лямбда-выражениях и т. д. Давайте сосредоточимся на этом анонимном внутреннем классе.

Анонимный внутренний класс — это внутренний класс без имени.По завершении определения также создается экземпляр, который часто тесно сочетается с ключевым словом new. Конечно, это не ограничивается классами, это может быть и интерфейс. , может появиться где угодно. Ниже мы определяем анонимный внутренний класс:

Его следует использовать, если вы должны переопределить метод класса или интерфейса. Анонимные внутренние классы Java можно создать двумя способами.

//首先定义一个普通类
public class Out {
    private String name;

    public void sayHello(){
        System.out.println("my name is :" + name);
    }
}
//定义和使用一个匿名内部类
public static void main(String [] args){
    Out out = new Out(){
        @Override
        public void sayHello(){
            System.out.println("my name is cyy");
        }
        public void showName(){
            System.out.println("hello single");
        }
    };
    out.sayHello();
}

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

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

Суммировать

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

После разговора о ссылке на функциональный интерфейс, стоящей за этим, лучше поговорить об этом.

конец

Внутренних классов так много, надеюсь, в будущем вам будет легче читать исходный код, ха-ха

ежедневные комплименты

Хорошо всем, вышеизложенное является полным содержанием этой статьи. Люди, которые могут видеть это здесь, всеталант.

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

Six Meridians Excalibur | Text [Original] Если в этом блоге есть какие-то ошибки, прошу покритиковать и посоветовать, буду очень признателен!