Типы данных в языке Java, делятся на две группы: примитивные типы (primitive types) и ссылочные типы (reference types).
Существует так же специальный тип данных – null. Переменную этого типа создать не возможно, но можно присвоить значение null (только) ссылочному типу данных.
Примитивные типы данных Java
Существует восемь примитивных типов данных в Java:
- Числовые данные (numeric types)
Целые типы (integral types) – byte, short, int, long, char
Вещественные типы (floating-point types) – float, double - Логический тип – boolean
Ссылочные типы данных Java
Существует четыре типа ссылочных данных в Java:
- Классы (class types)
- Интерфейсы (interface types)
- Переменные типов (type variables)
- Массивы (array types)
Так же существует очень много программистских мифов и фольклорных данных, которые по разному классифицируют принадлежность всех вышеперечисленных типов. Иногда, к примеру, тип char выделают в отельный тип, так как он представляет символы, но как вы можете убедится сами из оригинальной документации по Java – это не так. Char (символьный тип), в оригинальной документации, относят к целым типам данных, потому что над ними можно выполнять все те же самые операции, что и над обычными числовыми типами. Так же, почему то, очень часто пропускают типизированные переменные и в ссылочных типах указывать только три оставшихся. Или выделяют enum в отдельный тип ссылочных данных, хотя он относится к классам, так же поступают иногда и с классом String – выделяют его в отельный вид ссылочных данных, хотя это тоже класс. Все это тайна покрытая мраком, но свет изначальной документации выведет нас к истине!
На этом лирическое отступление закончим и зафиксируем знания о типах данных Java запомнив простую диаграмму приведенную ниже.
Если вы были внимательны, то заметили, что я подсветил желтым, чем отличаются примитивные типы данных от ссылочных. Это конечно не единственное различие, но самое основное. Еще раз повторюсь, что В Java все является объектом, за исключением примитивных типов. Так вот, примитивные типы передаются по значению, а ссылочные по ссылке. Масло масленное.
Чтобы разобраться с этим надо рассмотреть пример. И тут без объектов и классов опять не обойтись. Но сейчас мы упомянем ссылочные типы, только чтобы на их примере понять чем от них отличаются примитивные типы.
Приведу простую программу для демонстрации это принципиальной разницы:
А теперь приведу вывод этой программы в консоли Eclipse
Ключевые строки в листинге это 10, 12, 20 и 23. Как видим в строке 10 мы присвоили j то же значение что и i. И далее инкрементировали j. Затем вывели результат. Как видим i и j имеют разные значения. А вот с классом Dog, который является ссылочным типом данных все уже не так. В 20 строке мы присвоили экземпляру thatDog значение экземпляра thisDog, затем вывели результат, который показал одинаковые значения для обоих экземпляров, что не удивительно. Затем для экземпляра thatDog в 23 строке мы поменяли имя и снова вывели результат. И опять нам показали одинаковые значения. Это произошло потому, что ссылочные типы данных хранят не значение, а ссылку на объект и в данном случае происходит присвоение ссылки, а не значения. Таким образом оба экземпляра thisDog и thatDog указывают на один и тот же объект в памяти.
Может сейчас это все и не понятно, но в голове должно отложится и со временем все прояснится. Чтобы чуть более прояснить это, чуть чуть изменим программу и покажем что же на самом деле храниться в экземплярах thisDog и thatDog.
Я добавил строки 22 и 28, которые будут выводить значение того что реально хранится в объектах thisDog и thatDog. И вот вывод на консоль Eclipse:
Как видим и thisDog и thatDog хранят один и тот же указатель на область в памяти где располагается экземпляр класса Dog.
Ну и чтобы все стало еще чуть более понятней приведу исходник класса Dog:
Ну и коль уж заговорили о памяти то можно упомянуть, что переменные примитивных типов хранятся в стеке, который гораздо быстрее кучи, в которой хранятся объекты.
Так же, в какой-то мере, к типам данных можно отнести тип данных void. Переменную этого типа создать нельзя, так как этот тип используется только для того, чтобы обозначать методы классов которые ни чего не возвращают.
Хорошо изложен материал, спасибо
ОтветитьУдалить