Цель этого курса - помочь вам более эффективно использовать Java. Существуют некоторые расширенные темы, включая создание объектов, параллелизм, сериализацию, размышления и другие расширенные функции. Этот курс будет направлять ваше путешествие на знание Java.
1. Введение
В рейтинге языка программирования TIOBE на Java Language, разработанном Sun в 1995 году, является одним из наиболее широко используемых языков программирования в мире. Как общий язык программирования, Java Language очень привлекателен для инженеров по разработке программного обеспечения из -за мощных инструментов и среды выполнения, простого синтаксиса, богатой поддержки платформы (написанного одновременно, везде) и чрезвычайно активной поддержки сообщества.
В этой серии статей охватывается расширенный контент, связанный с Java, поэтому предполагается, что читатель уже обладает базовыми языковыми знаниями. Это не полное справочное руководство, а исчерпывающее руководство по выводу ваших навыков на следующий уровень.
Этот курс содержит большое количество фрагментов кода. Чтобы провести сравнение, некоторые другие стороны предоставит примеры Java 7 и Java 8 одновременно.
2. Пример строительства
Как объектно-ориентированный язык, создание объекта, пожалуй, одна из самых важных концепций на языке Java. Конструктор играет важную роль в инициализации экземпляров объектов, а Java предоставляет множество способов определения конструкторов.
2.1 Неявный (сгенерированный) метод строительства
Java не позволяет объявлять конструкторы при определении классов, и это не означает, что нет конструктора. Давайте посмотрим на определение следующего класса:
пакет com.javacodegeeks.advanced.construction; открытый класс noconstructor {}Этот класс не определяет конструктор, но компилятор Java косвенно генерирует его, что позволит нам использовать новое ключевое слово для создания новых экземпляров объекта.
Окончательный нокостр noconstructorinstance = new Noconstructor ();
2.2 Метод конструкции без параметра
Конструктор без параметра является самым простым способом заменить компиляцию Java и генерировать конструкторы путем явных объявлений.
Пакет com.javacodegeeks.advanced.construction; открытый класс noargconstructor {public noargconstructor () {// Тело конструктора здесь}}}}}}}При создании нового экземпляра объекта с использованием нового ключевого слова будет вызван выше конструктор.
2.3 Метод конструкции, похожий на параметры
Метод построения параметров является наиболее интересным и широко используемым, а создание новых экземпляров настроено путем указания параметров. В следующем примере определяется конструктор с двумя параметрами.
пакет com.javacodegeeks.advanced.construction; открытый класс constructorwitharguments {public constructorWitharguments (конечная строка Arg1, final String arg2) {// Тело конструктора здесь}}В этом сценарии при использовании нового ключевого слова для создания экземпляра необходимо предоставить два параметра, определенные на методе строительства.
Окончательный конструкторвитаргенции constructorWitharguments = new ConstructorWitharguments («arg1», «arg2»);
Интересно, что конструкторы могут быть вызваны друг к другу через это ключевое слово. На практике рекомендуется цепорить несколько конструкторов, используя это для уменьшения дублирования кода и иметь единую запись инициализации на основе объекта. В качестве примера, следующий код определяет конструктор только с одним параметром.
public ConstructorWitharguments (Final String arg1) {this (arg1, null);}2.4 Инициализируйте кодовый блок
В дополнение к построению методов, Java также предоставляет логику для инициализации путем инициализации блоков кода. Хотя это использование редко, не вредно знать об этом больше.
пакет com.javacodegeeks.advanced.construction; public class initializationblock {{// код инициализации здесь}}С другой стороны, инициализация кодовых блоков также может рассматриваться как неявные методы строительства без параметров. В конкретном классе можно определить несколько блоков кода инициализации, и они вызываются в порядке, которые они находятся в коде при выполнении, как показано в следующем коде:
пакет com.javacodegeeks.advanced.construction; public class initiazationblocks {{// код инициализации здесь} {// код инициализации здесь}}Действительно инициализация кодовых блоков не предназначена для замены конструктора, но они могут появиться одновременно. Но помните, что код инициализации будет выполнен до того, как вызов метода конструктора скоро.
пакет com.javacodegeeks.advanced.construction; public class initiazationblockandconstructor {{// код инициализации здесь} public initiazationblockandConstructor () {}}2.5 Убедитесь, что построение значений по умолчанию
Java предоставляет определенную гарантию инициализации, и программисты могут напрямую использовать результат инициализации. Неинитированные экземпляры и переменные класса (статика) будут автоматически инициализированы до соответствующих значений по умолчанию.
Введите значение по умолчанию
Booleanfalse
byte0
шорт0
int0
Long0l
char/u0000
float0.0f
Double0.0d
Ссылка на объект NULL
Таблица 1
Мы используем следующий пример для проверки значений по умолчанию в приведенной выше таблице:
пакет com.javacodegeeks.advanced.construction; public class инициализация withdefaults {private boolean booleanmember; частный байт -байт -заменька; частный короткий шорт -член; частный int intmember; частный длинный длинный длинношерский; Частный Чар Шармембер; Частный поплавок; частное двойное дублем -помнители; Частный объект SERECTEMEMEMEMEMEMEMEMEMEMEMEMENT; public инициализация withdefaults () {System.out.println ("booleanmember =" + booleanmember); System.out.println ("bytemember =" + bytemember); System.out.println ("shortmember =" + shortmember); System.out.println ("intmember =" + intmember); System.out.println ("longmember =" + longmember); System.out.println ("charmember =" + parment.codepointat (new char [] {charmember}, 0)); System.out.println ("floatmember =" + floatmember); System.out.println ("DoubleMempemement =" + DoubleMempement); System.out.println ("serficemember =" + serficemember); }}После создания объекта, используя новое ключевое слово:
Окончательная инициализация с инициализацией withdefaults = новая инициализация withdefaults (),
Вы можете увидеть результат вывода из консоли следующим образом:
booleanmember = falsebytemember = 0shortmember = 0intmember = 0longmember = 0charmember = 0floatmember = 0,0doublemember = 0,0Referencemember = null
2.6 видимость
Конструктор следует по правилам видимости Java и может определить, может ли конструктор можно вызвать в других классах с помощью модификаторов управления доступом.
Модификатор пакета видимость подкласса видимости общественная видимость
общественный видимый видимый видимый видимый видимый
Защищенный видимый, видимый невидимый невидимый
<Без модификатора> видимо, не видимый, не видимый
Частный невидимый невидимый невидимый невидимый таблица 2
2.7 Утилизация мусора
Java (JVM, если быть точным) имеет автоматический механизм сбора мусора. Проще говоря, когда создается новый объект, он автоматически распределяет свою внутреннюю часть; Затем, когда объект больше не ссылается, они будут автоматически уничтожены, а соответствующая память будет переработана.
Java Collection Marbage принимает механизм утилизации поколений и основан на предположении, что «большинство объектов имеют короткую жизнь» (то есть они не будут повторяться вскоре после создания объекта, поэтому они могут быть безопасно уничтожены). Большинство программистов обычно считают, что создание объектов в Java очень неэффективно, поэтому они должны как можно больше избежать создания новых объектов. На самом деле, это понимание неверно. Накладные расходы создания объектов в Java довольно низкие и быстрые. Огромные накладные расходы в реальном поколении являются ненужными долгосрочными объектами выживания, поэтому они в конечном итоге будут перенесены на старость и приведут к тому, что они останавливаются в мире.
2.8 Обоснователи объекта
Мы говорили о темах, связанных с методами строительства и инициализацией объекта, но мы не упомянули их негативную сторону: разрушение объекта. Главным образом потому, что Java использует механизмы сбора мусора для управления жизненным циклом объектов, уничтожение ненужных объектов, и освобождение необходимой памяти становится обязанностью сбора мусора.
Тем не менее, Java по -прежнему предоставляет еще одну особенность, аналогичную финализатору деструктора, которая берет на себя ответственность за очистку нескольких ресурсов. Финализатор, как правило, рассматривается как опасная вещь (потому что он может принести различные побочные эффекты и проблемы с производительностью). Обычно финализатор не требуется, поэтому старайтесь избегать его (за исключением редких сценариев, которые содержат большое количество местных объектов). Синтаксис и автокланируемый интерфейс Try-with-resources, представленный в Java 7, можно использовать в качестве альтернативы финализаторам, и можно записать следующий краткий код:
try (final inputstream in = files.newinputstream (path)) {// код здесь}3. Статическая инициализация
Выше мы узнали о строительстве и инициализации экземпляров класса. Кроме того, Java также поддерживает конструкцию инициализации на уровне класса, называемую статической инициализацией. Статическая инициализация аналогична блоку кода инициализации, описанного выше, за исключением того, что существуют дополнительные статические модификации ключевых слов. Следует отметить, что статическая инициализация будет выполняться только один раз при загрузке класса. Примеры следующие:
Подобно инициализации кодовых блоков, в классе можно определить несколько блоков статической инициализации, а их положение в классе определяет порядок, в котором они выполняются при инициализации. Примеры следующие;
Пакет com.javacodegeeks.advanced.construction; открытый класс Staticinitializationblocks {static {// Статическая инициализация здесь} static {// Статическая инициализация здесь}}Поскольку блоки статической инициализации могут быть запускаются несколькими потоками, выполняющимися параллельно (когда класс изначально загружается), время выполнения JVM гарантирует, что инициализированный код выполняется только один раз в потоке-безопасном способе.
4. Режим конструктора
Разнообразные удобные для понимания конструкторы (создатель) были введены в сообщество Java на протяжении многих лет. Ниже мы изучим несколько наиболее популярных: режим Синглтона, режим вспомогательного класса, заводский режим и инъекция зависимости (также известный как инверсия управления).
4.1 Синглтонский режим
Singleton - это долгая история, но противоречивая модель в сообществе разработки программного обеспечения. Основная концепция синглтонского рисунка состоит в том, чтобы в любое время данный класс создается только один объект. Несмотря на то, что это звучит просто, существует много дискуссий о том, как создавать объекты правильным и безопасным образом. В следующем коде показана простая версия реализации шаблона Singleton:
пакет com.javacodegeeks.advanced.construction.patterns; Public Class Naivesingleton {Private Static Naivesingleton Extance; private naivesingleton () {} public static naivesingleton getInstance () {if (ancess == null) {exance = new Naivesingleton (); } return Encement; }}Существует хотя бы одна проблема с приведенным выше кодом: несколько объектов могут быть созданы в многопоточном сценарии параллелизма. Разумным способом реализации (но не отсроченной нагрузки) является использование статического свойства класса. следующее:
Окончательное свойство Class.package com.javacodegeeks.advanced.construction.patterns; public class eagersingleton {private Static Final Eagersingleton Extance = new Eagersingleton (); private eagersingleton () {} public static eagersingleton getInstance () {return Encement; }}Если вы не хотите тратить ценные ресурсы и хотите, чтобы объекты Singleton были созданы только тогда, когда они действительно необходимы, вам необходимо использовать явный метод синхронизации. Этот метод может снизить параллелизм в многопоточных средах (более подробная информация о параллелизме Java будет описана в лучших практиках Java 9-концентрации).
пакет com.javacodegeeks.advanced.construction.patterns; открытый класс Lazysingleton {частный статический экземпляр Lazysingleton; private lazysingleton () {} public static synchronized lazysingleton getInstance () {if (ancement == null) {encos = new lazysingleton (); } return Encement; }}В настоящее время модели синглтона больше не считаются хорошим выбором во многих сценариях, потому что они делают код менее простым в тестировании. Кроме того, генерация режима впрыска зависимостей также делает синглтонский режим ненужным.
4.2 Инструменты/вспомогательные классы
Паттерн класса инструментов/класса справки довольно популярен среди разработчиков Java. Его основная концепция состоит в том, чтобы использовать неинституционализированные классы (объявляя частные конструкторы), дополнительные окончательные (более подробная информация о объявлении окончательных классов будет введена в ключевых словах Java Advanced 3-Class и интерфейса) и статических методов. Примеры следующие:
Пакет com.javacodegeeks.advanced.construction.patterns; public final Class helperclass {private helperclass () {} public static void helpermethod1 () {// Тело метода здесь} public static void helpermethod2 () {// тело здесь}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}.Многие опытные разработчики считают, что этот шаблон сделает классы инструментов контейнером для различных неактуальных методов. Поскольку некоторые методы не имеют подходящего размещения, но их необходимо использовать другими классами, они будут ошибочно помещены в класс инструментов. Этого дизайна также следует избегать в большинстве сценариев: всегда будут лучшие способы повторного использования кода, сохраняя код ясным и кратким.
4.3 Заводская модель
Заводская модель оказалась чрезвычайно мощным инструментом для разработчиков, и есть много способов реализовать ее в Java: фабричные методы и абстрактные фабрики. Самый простой пример - использовать статический метод для возврата экземпляра конкретного класса (фабричный метод), следующим образом:
пакет com.javacodegeeks.advanced.construction.patterns; public class book {private book (final string title) {} public Static Book Newbook (Final String title) {return New Book (Title); }}Хотя использование этого метода может улучшить читаемость кода, часто противоречиво, что трудно дать сценариям более богатых заводов из Ньюбайна. Другим способом реализации заводской шаблона является использование интерфейсов или абстрактных классов (абстрактные фабрики). Следующим образом, мы определяем заводский интерфейс:
публичный интерфейс BookFactory {Book NewBook ();}В зависимости от галереи изображений, у нас может быть много различных реализаций Ньюбука:
Библиотека открытого класса реализует BookFactory {@Override Public Book NewBook () {return New PaperBook (); }} public Class Kindlelibrary реализует BookFactory {@Override public book newbook () {return new kindlebook (); }}Теперь различные реализации BookFactory блокируют различия в конкретных книгах, но предоставляют общий метод Ньюбайна.
4.4 Инъекция зависимости
Инъекция зависимости (также известная как управляющая инверсия) рассматривается дизайнерами класса как хорошую практику дизайна: если некоторые экземпляры класса зависят от экземпляров других классов, должны быть предоставлены те экземпляры (вводятся) с помощью методов конструктора (или методов сеттера, политик и т. Д.), А не созданы самим человеком. Давайте посмотрим на следующий код:
пакет com.javacodegeeks.advanced.construction.patterns; import java.text.dateformat; импорт java.util.date; public class -зависимый публичный формат строки (дата окончательной даты) {return format.format (date); }}Зависимый класс требует экземпляра класса DateFormat и получается с помощью dateformat.getDateInstance () при создании объекта. Лучший способ сделать то же самое, построив параметры метода:
пакет com.javacodegeeks.advanced.construction.patterns; import java.text.dateformat; import java.util.date; public class -зависимый {частный окончательный формат Dateformat; Public Desipend (Final DateFormat Format) {this.format = format; } public String Format (окончательная дата дата) {return format.format (date); }}В приведенном выше примере все зависимости экземпляра класса предоставляются извне, что позволяет легко настраивать дату и простой для написания тестового кода.