вторник, 29 сентября 2020 г.

Ключевые слова Void и Static

    Методы могут возвращать или не возвращать значения.

    Тип возвращаемых данных указывают при объявлении метода - перед его именем.


Void

    Ключевое слово (модификатор) void (пустой) означает, что метод не возвращает никаких данных (значений) в переменные как результат своей работы, а просто, к примеру, выводит на экран строку.
   Если метод возвращает какие-то данные, то вместо void нужно указать возвращаемый тип (например int), а в теле метода используется хотя бы один оператор return вида:
return выражение/переменная
    где выражение/переменная - это возвращаемое значение.


    Этот оператор возвращает переменную или результат вычисления выражения в точку вызова метода. Тип выражения должен совпадать с типом возвращаемого значения.
    Нередко возникает потребность в методах, которые возвращают значение того или иного типа: например, int для целых значений, (к примеру, если метод должен найти большее из двух целых чисел) float - для вещественных или имя класса для типов данных, определенных программистом.
   Однако, можно использовать return просто для выхода из метода: если стоит модификатор void, то выход из метода выполняется либо после выполнения последнего оператора тела метода, либо в результате выполнения оператора return; (таких операторов в теле метода может быть несколько).


Static

   Ключевое слово (модификатор) static в Java используется для управления памятью.
 
   Обозначенные ключевым словом static переменные принадлежат всему классу, а не конкретному объекту класса.
   Когда член класса объявлен как static (статический), он доступен до создания каких-либо объектов его класса и без ссылки на какой-либо объект.
 
   (В некоторых случаях нужно определить член класса, который будет использоваться независимо от любого объекта этого класса. Обычно обращение к члену класса должно выполняться только в сочетании с объектом его класса, однако можно создать член класса, который может использоваться самостоятельно, без ссылки на конкретный экземпляр: чтобы создать такой член, в начало его объявления нужно поместить ключевое слово static.)
 
 
   Статическими (объявленными с помощью ключевого слова (модификатора) static) могут быть: 
 
   (Ключевое слово static может использоваться при описании полей и методов класса)
 
 
   а) переменная класса  (поле класса)
 
   Статическая переменная может использоваться для обозначения общего свойства всех объектов, которое не является уникальным для каждого объекта.
    Статическое свойство Java является общим для всех объектов. Переменные экземпляров, объявленные как static, по существу являются глобальными переменными.
   При объявлении объектов их класса программа не создает никаких копий переменной static. Вместо этого все экземпляры класса совместно используют одну и ту же статическую переменную. Например название компании, колледжа и т. д. Статическая переменная задействует память только один раз во время загрузки класса: если какой-либо объект изменяет значение статической переменной, она сохраняет свое значение.
 
 
   б) метод класса
 
   Если ключевое слово static применяется в объявлении метода, то это статический метод Java.
 
• Статический метод относится к классу, а не к объекту класса
• Статический метод можно вызывать без создания экземпляра класса
   (обычный метод класса вызывается у экземпляра класса, а статический – у самого класса)
   (Если не использовать ключевое слово static и сделать метод нестатичным, необходимо создать объект класса для его вызова.)
 
• Статический метод может получать доступ к статическому члену и изменять его значение
• Методы, в объявлении которых использовано ключевое слово static, могут непосредственно работать только с локальными и статическими переменными.
• Они могут вызывать только другие статические методы.
• Они не могут ссылаться на члены типа this или super.
• Основной main метод Java является статическим, постольку, поскольку объект не является обязательным для вызова статического метода, если он был не статическим. Этот метод объявляют как static, поскольку он должен быть объявлен до создания любых объектов.
    Виртуальная машина сначала вызывает Java public static void main(), что приводит к выделению дополнительной памяти.
 
   в) блок
   Если для инициализации переменных типа static нужно выполнить вычисления, можно объявить статический блок, который будет выполняться только один раз при первой загрузке класса.
• Применяется для инициализации статического члена
• Выполняется перед методом main во время загрузки класса - внутренний класс

 
Не статические методы:

    Не статические методы в Java используются чаще, чем статические методы.
   Статические методы принадлежат всему классу, а не статические методы могут принадлежать любому объекту, экземпляру класса, а не всему классу. Такие методы можно вызвать только на конкретных созданных объектах.
   Не статические методы могут получать доступ и изменять поля объекта.

четверг, 24 сентября 2020 г.

Видимость переменных. Служебные слова-модификаторы доступа public, private, protected (Access modifiers)

Видимость переменных

Правила видимости переменных:

1 Переменная, объявленная в методе, существует(видна) с начала объявления метода до конца метода.

2 Переменная, объявленная в блоке кода (например if { }), существует до конца этого блока кода.

3 Переменные-аргументы метода существуют везде внутри метода.

4 Переменные класса или объекта существуют все время жизни содержащего их объекта.

(Их видимость дополнительно регулируется специальными модификаторами доступа: public, private).

5 Статические переменные классов существуют все время работы программы.

(Их видимость также определяется модификаторами доступа).


Служебные слова-модификаторы доступа

 

    Перед именами классов, методов и переменных могут стоять служебное слова-модификаторы доступа public, private, protected, позволяющие управлять доступностью (видимостью и возможностью использования) методов и переменных (сообщать компилятору Java параметры их доступности).

   (Эти служебные слова определяют места в коде, где к этим данным можно обратиться)

   Каждому методу или переменной можно указывать только один модификатор доступа.

   Модификаторы private и protected нужны, чтобы защитить поля от нежелательного изменения или доступа из других программ, которые используют класс.

 

default (package-private) (без модификатора, модификатор по-умолчанию)

 Область доступа - для всех классов данного пакета: члены класса доступны (видны и могут быть использованы) только внутри пакета. 

   Если переменная или метод не помечены никаким модификатором, то считается, что они помечены «модификатором по умолчанию». Переменные или методы с таким модификатором (т.е. вообще без какого-нибудь модификатора) видны всем классам пакета, в котором они объявлены и только им.

   Этот модификатор еще иногда называют «package», так как доступ к переменным и методам открыт для всего пакета, в котором находится их класс.
 

  public
 
   Public - модификатор доступа, делающий данный класс публичным, общедоступным/
   Область доступа - без ограничений: помеченные им члены класса (методы и поля) доступны без ограничений из любого места программы (видны без ограничений и могут быть использованы в других классах, в других программах).
   Это самая высокая степень открытости - никаких ограничений нет. 

  private 

Область доступа - только из своего класса (в котором объявлен): помеченные им методы и поля (переменные) доступны (видны и могут быть использованы) только в этом классе.

   К переменной или методу, помеченному модификатором private, можно обращаться только из того же класса, где он объявлен. Для всех остальных классов помеченный метод или переменная  невидимы.

   Это самая высокая степень закрытости – только свой класс. 


  protected 

Область доступа - из своего класса (в котором объявлен) и его потомков: помеченные им методы и поля доступны (видны и могут быть использованы) только в этом классе или в классах, наследующих его с помощью extends. (внутри пакета и в наследниках)


   Последовательность слов-модификаторов по убыванию уровня закрытости: private, default, protected, public.
   *Во время наследования возможно изменения модификаторов доступа в сторону большей видимости - это сделано для того, чтобы не нарушался принцип LSP (Liskov substitution principle) для наследуемого класса. 


МодификаторДоступ из своего класса (в котором объявлен)
Доступ для классов своего пакетаДоступ из любого класса
public+++
без модификатора (package)++-
private+--

понедельник, 14 сентября 2020 г.

Полезные книги и ссылки

Ссылки:

 Официальная документация по Java: https://docs.oracle.com/javase/8/docs/index.html


 Список книг:

   Кэти Сиерра, Берт Бейтс - Изучаем Java (Head-First Java)

   Герберт Шилдт - Java 8. Полное руководство

   Брюс Эккель - Философия Java

   Чарльз Петцольд - Код

   Адитья Бхаргава - Грокаем алгоритмы



Какое программное обеспечение необходимо для программирования на Java

   Для того, чтобы начать программировать на Java необходимо:

 

   1 Установить и настроить программное обеспечение для разработки и запуска программ - JDK (Java Development Kit):

   - Перейти на сайт Oracle https://www.java.com/ru/download/help/windows_manual_download.xml

   - Выбрать и скачать установочный файл в зависимости от вашей операционной системы

   - Выполнить установку, следуя рекомендациям программы-установщика

   - Настроить переменную окружения, если установка производится на Windows

      Инсталлятор Java не выполняет настройку переменных окружения, поэтому необходимо сделать это вручную после установки.

   Во-первых, необходимо установить переменную JAVA_HOME, которая должна указывать на директорию, в которую установлена Java:

   Для Windows:

   Для установки переменных окружения открыть свойства компьютера, например, через меню “Пуск”.

   Затем нужно выбрать “Дополнительные параметры системы”, в открывшемся диалоге перейти на вкладку “Дополнительно” и нажать кнопку “Переменные среды”, после чего появится диалог настройки переменных окружения.

   Если переменная окружения JAVA_HOME уже есть - необходимо её отредактировать, если нет - создать новую.

   В качестве значения указывается путь к директории, куда установлена Java. К примеру:

   c:\Program Files\Java\jdk1.8.0_25\, если устанавливался JDK

   либо c:\Program Files\Java\jre1.8.0_25\, если устанавливался только JRE.

   Во-вторых, чтобы можно было запускать Java из консоли, переменная PATH должна быть правильно настроена (Эта переменная указывает операционной системе список директорий, в которых нужно искать исполняемые файлы):

  После установки значения переменной JAVA_HOME требуется отредактировать значение переменной PATH, добавив туда путь к директории, где системе нужно искать исполняемые файлы Java, то есть %JAVA_HOME%\bin

   NB! Если устанавливается JDK, то в названии директории указывается номер версии, поэтому впоследствии, при установке более новых версий, необходимо менять значение переменной окружения JAVA_HOME.

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

 

   Удаление лишних файлов:

   Запускается консоль (cmd) и выполняется команда where java.

   Результат - путь к исполняемому файлу java.exe, который операционная система должна успешно обнаружить в том месте, куда установлен Java.

   Если файл не нашёлся - значит неправильно настроена переменная PATH.

   Иногда бывает, что находятся лишние исполняемые файлы

   (Происходит это из-за того, что инсталлятор Java вместо того, чтобы правильно настроить переменные окружения, пытается положить исполняемые файлы в директорию C:\Windows\system32 )

   Это может привести к рассогласованию версий Java (в разных директориях разные версии).

   Поэтому надо удалить из каталога C:\Windows\system32 исполняемые файлы java.exe, javaw.exe и javaws.exe, если они там обнаружатся.

      

   2 Скачать и установить одну из сред разработки программного обеспечения (приложение для написания программ на Java) - IDE (Integrated Development Environment) 

   Среда разработки  может включать в себя такие инструменты, как:

   - текстовый редактор с подсветкой кода

   - компилятор или интерпретатор

   - браузер классов, инспектор объектов и диаграмму иерархии классов

   - средства автоматизации сборки

   - отладчик

   - средства для интеграции с системами управления версиями (Git)

   - инструменты для упрощения конструирования графического интерфейса пользователя

 

   Примеры IDE:

      - IntelliJ IDEA

      - Eclipse

      - NetBeans

      - JCreator

      - Notepad (Блокнот)

Что такое JVM JRE JDK IDE

   IDE (Integrated Development Environment) (Интегрированная среда разработки) - среда разработки программного обеспечения (приложение для написания программ).

   Среда разработки может включать в себя такие инструменты, как: текстовый редактор с подсветкой кода, компилятор или интерпретатор, браузер классов, инспектор объектов и диаграмму иерархии классов, средства автоматизации сборки, отладчик, средства для интеграции с системами управления версиями (Git), инструменты для упрощения конструирования графического интерфейса пользователя.

   Примеры IDE: - IntelliJ IDEA - Eclipse - NetBeans - JCreator - Notepad (Блокнот)


    JDK (Java Development Kit) (Набор для разработки Java) - набор инструментов для разработчика, необходимых для написания программ на Java.

   В состав JDK входит сам язык Java (его синтаксис), Java-машина, компилятор Java-классов и другое, что может понадобиться Java-разработчику: стандартные библиотеки классов Java (стандартный набор классов), различные вспомогательные утилиты, документацию, примеры программного кода, JRE и JVM.

 

   Скачать JDK для подходящей платформы можно по ссылке



   JRE (Java Runtime Environment) - среда выполнения (исполнения) Java.

      (Минимальная реализация виртуальной машины, необходимая для исполнения готовых Java-приложений)

      JRE включает в себя реализацию виртуальной машины Java (JVM для конкретной платформы), набор основных библиотек Java-классов, необходимых для выполнения программ на Java, и загрузчик классов Java.

      В отличие от JDK, не содержит компилятора и других средств разработки.

      Подробнее о работе JRE можно прочитать по ссылке.


   JVM (Java Virtual Machine) - виртуальная (то есть реализованная программно) машина Java.

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

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

      JVM позволяет запускать программы, написанные на Java, на любой платформе (при условии, что JVM реализована для неё).

   Под платформой обычно понимают сочетание аппаратной (процессор) и программной (операционная система, ОС) части.

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

   Также JVM осуществляет управление и оптимизацию памяти, используемой приложением.


   Виртуальная машина (JVM) для выполнения программы запускается с помощью утилиты java.


   Принцип использовани JVM:

      1) Программист создаёт файлы программы с расширением .java

      2) Файлы программы с расширением .java компилируются и получаются файлы с расширением .class, в которых уже хранится байт-код

      3) JVM считывает байт-код, интерпретирует его в машинный код, передавая его для исполнения платформе

      4) Команды программы выполняются платформой


   Подробнее о работе JVM можно прочитать здесь: https://javaika.blogspot.com/2018/11/2-java.html

   А также здесь: https://topjava.ru/blog/what-is-the-jvm


   Ниже приведена коцептуальная диаграмма продуктов Oracle, составляющих Java SE:

         Здесь:

            Java language - язык Java (его синтаксис).

            Java - Java runtime launcher - консольная утилита,позволяющая запустить программу. Она нужна для запуска JVM с полученными class-файлами.

            Javac - Java compiler (компилятор) - консольная утилита для компиляции кода. Она компилирует java-файлы в class-файлы, содержащие байт-код.

            Javadoc - Java documentation generator - утилита для генерации документации на основе комментариев в коде

            Jar - Java archive tool - утилита для работы с Jar.

            Javap - Java class file disassembler

            ...

            Java Web Start - Java Web Services Tools


   О том, как происходит напиcание и исполнение программ с их помощью можно прочитать здесь: https://javaika.blogspot.com/2018/11/2-java.html

вторник, 8 сентября 2020 г.

Управление исключениями (возникающими ошибками) в Java

  Исключение в программировании - это возникновение ошибок и непредвиденных ситуаций при выполнении программы.

  Исключения (ошибки при выполнении программы) могут возникать в результате:

   - неправильных действий пользователя

   - отсутствии необходимого ресурса на диске

   - потери соединения с сервером по сети

   - ошибки программирования

   - неправильное использование API.

 

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

   (чтобы предупредить и решить исключительные ситуации в программе, для того чтобы её выполнение могло быть продолжено)

   В частности, механизм исключений позволяет защитить написанный код (программный интерфейс) от неправильного использования пользователем за счет валидации (проверки) входящих данных. 

  Использование исключений в Java позволяет повысить отказоустойчивость программы за счет использования «запасных» путей, отделить логику основного кода от кода обработки исключительных ситуаций за счет использования блоков catch, а также дает возможность переложить обработку исключений на пользователя нашего кода с помощью throws.

 

   Обработка исключений в Java основана на использовании в программе следующих ключевых слов

 

try, catch, finally, throws

 

   1) try – определяет (заключает под собой) блок кода, в котором может произойти исключение;

   2) catch – определяет (заключает под собой) блок кода, в котором происходит обработка исключения;

   (Действия при сбое, который может случиться внутри оператора try)

   3) finally – определяет (заключает под собой) блок кода, который является необязательным, но при его наличии выполняется в любом случае независимо от результатов выполнения блока try.

(Блок finally часто используется для того, чтобы закрыть открытые в блоке try потоки или освободить ресурсы. Однако при написании программы не всегда возможно уследить за закрытием всех ресурсов. Для облегчения этой задачи существует конструкция try-with-resources, которая автоматически закрывает ресурсы, открытые в блоке try).

   Эти ключевые слова используются для создания в программном коде специальных обрабатывающих конструкций: try{}catch, try{}catch{}finally, try{}finally{}.

   На стадии разработки программы мы «ограждаем» опасные участки кода в отношении исключений с помощью блока try{}, предусматриваем «запасные» пути с помощью блока catch{}, в блоке finally{} мы пишем код, который выполняется в программе при любом исходе.

 

   При появлении исключения в блоке try обработчик исключения ищется в следующем за ним блоке catch. Если в catch есть обработчик данного типа исключения – управление переходит к нему. Если нет, то JVM ищет обработчик этого типа исключения в цепочке вызовов методов до тех пор, пока не будет найден подходящий catch. После выполнения блока catch управление передается в необязательный блок finally. В случае, если подходящий блок catch не найден, JVM останавливает выполнение программы, и выводит стек вызовов методов – stack trace, выполнив перед этим код блока finally при его наличии.

   Переменные, определенные в try не могут быть использованы в catch или finally, этот код не скомпилируется. Причина в том, что неизвестно, где именно в блоке try могло быть вызвано исключение, например, возможно, что исключение было вызвано до того, как был объявлен объект.


  4) throw – используется для возбуждения исключения

  5) throws – Это ключевое слово в сигнатуре метода означает, что при определенных условиях метод, может выбросить исключение

    (Ключевое слово throws используется когда не планируется обрабатывать исключение в своем методе, но необходимо предупредить пользователей метода о возможных исключительных ситуациях)

   Такое предупреждение является частью интерфейса метода и предоставляет право пользователю на собственный вариант реализации обработчика исключения (предоставляя написание кода по обработке исключения в Java пользователю метода.).

   После throws указывается тип выбрасываемого исключения.

 

   Типы выбрасываемых исключений:

   Обычно это наследники класса Exception Java.

   Поскольку Java является объектно-ориентированным языком, все исключения в Java представляют собой объекты.

   При возникновении ошибки в процессе выполнения программы исполняющая среда JVM создает объект нужного типа из иерархии исключений Java.

   Иерархия исключений java:




   Throwable - название класса "предка", от которого унаследовано множество возможных исключительных ситуаций.

   Далее всё это множество исключительных ситуаций можно разделить на две группы:

   1) Непроверяемые на стадии компиляции (неконтролируемые) (unchecked)

   Это Error (исключения, унаследованные из класса Error) + RuntimeException (часть исключений - наследников класса Exception)

  RuntimeException – исключения, генерируемые JVM во время выполнения программы. Часто причиной возникновения их являются ошибки программирования.

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

   Это ошибки, возникающие при выполнении программы в результате сбоя работы JVM, переполнения памяти или сбоя системы. Обычно они свидетельствуют о серьезных проблемах, устранить которые программными средствами невозможно, такими как деление на 0, нулевой указатель и т.п.  

 

Список непроверяемых исключений:

   ArithmeticException - арифметическая ошибка, например, деление на ноль

   ArrayIndexOutOfBoundsException - выход индекса за границу массива

   ArrayStoreException - присваивание элементу массива объекта несовместимого типа

   ClassCastException - неверное приведение

   EnumConstantNotPresentException - попытка использования неопределённого значения перечисления

   IllegalArgumentException - неверный аргумент при вызове метода

   IllegalMonitorStateException - неверная операция мониторинга

   IllegalStateException - некорректное состояние приложения

   IllegalThreadStateException - запрашиваемая операция несовместима с текущим потоком

   IndexOutofBoundsException - тип индекса вышел за допустимые пределы

   NegativeArraySizeException - создан массив отрицательного размера

   NullPointerException - неверное использование пустой ссылки

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

   NumberFormatException - неверное преобразование строки в числовой формат SecurityException - попытка нарушения безопасности

   StringIndexOutOfBounds - попытка использования индекса за пределами строки

   TypeNotPresentException - тип не найден

   UnsupportedOperationException - обнаружена неподдерживаемая операция

 

 

   2) Проверяемые на стадии компиляции (предвидимые еще на стадии написания программы) (контролируемые) (checked)

   Это Exception (кроме RuntimeException)

   Основная часть работы разработчика на Java при работе с исключениями – обработка таких ситуаций: проверяемые исключения должны быть явно пойманы в теле метода или объявлены в секции throws метода.

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


   Список проверяемых системных исключений, которые можно включать в список throws:

   ClassNotFoundException - класс не найден

   CloneNotSupportedException - попытка клонировать объект, который не реализует интерфейс Cloneable

   IllegalAccessException - запрещен доступ к классу

   InstantiationException - попытка создать объект абстрактного класса или интерфейса

   InterruptedException - поток прерван другим потоком

   NoSuchFieldException - запрашиваемое поле не существует

   NoSuchMethodException - запрашиваемый метод не существует

   ReflectiveOperationException - исключение, связанное с рефлексией

 

   Пример использования ключевых слов в java-программе:

//метод считывает строку с клавиатуры

public String input() throws MyException {//предупреждаем с помощью throws,
// что метод может выбросить исключение MyException
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
//в блок try заключаем код, в котором может произойти исключение, в данном
// случае компилятор нам подсказывает, что метод readLine() класса
// BufferedReader может выбросить исключение ввода/вывода
    try {
        s = reader.readLine();
// в блок  catch заключаем код по обработке исключения IOException
    } catch (IOException e) {
        System.out.println(e.getMessage());
// в блоке finally закрываем поток чтения
    } finally {
// при закрытии потока тоже возможно исключение, например, если он не был открыт, поэтому “оборачиваем” код в блок try
        try {
            reader.close();
// пишем обработку исключения при закрытии потока чтения
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    if (s.equals("")) {
// мы решили, что пустая строка может нарушить в дальнейшем работу нашей программы, например, на результате этого метода нам надо вызывать метод substring(1,2), поэтому мы вынуждены прервать выполнение программы с генерацией своего типа исключения MyException с помощью throw
        throw new MyException("String can not be empty!");
    }
    return s;
}
 

 Этот же пример с помощью try-with-resources:

public String input() throws MyException {
    String s = null;
    try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){
        s = reader.readLine();
   } catch (IOException e) {
       System.out.println(e.getMessage());
   }
    if (s.equals("")){
        throw new MyException ("String can not be empty!");
    }
    return s;
}

Наследование в Java

   «родительское/дочернее»     Наследование (inheritance) - свойство системы, позволяющее описать (создать) новый класс на основе уже су...