Top.Mail.Ru

Перечень уроков по Java

5. Типы данных

Любые данные – константы, переменные, значения функций характеризуются в Jave типом данных.

Язык программирования Java является языком со строгой типизацией. Это означает, что все объекты программы (переменные, константы и т.д.) должны быть описаны до первого использования. Описания информируют транслятор, во-первых, о существовании используемых переменных и других объектов, во-вторых, указывают на свойства этих объектов.

Тип данных определяет:

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

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

Множество типов данных языка Java обычно делят на две группы:

    • Примитивныеprimitive
    • Ссылочные – reference

Ссылочные типы являются объектами. Примитивные типы – это скалярные величины. В языках программирования, не являющихся объектно-ориентированными, примитивные типы называют простыми типами.

Примитивный тип данных (Primitive)

Примитивные типы Java не являются объектами. Всего их восемь, к ним относятся: byte, short, int, long, float, double, charи boolean.

Каждый примитивный тип как член класса имеет значение по умолчанию:

Примитивный тип Значение по умолчанию
byte, short, int, long 0
float 0.0F
double 0.0D
char 0; или ‘\u0000’
boolean false

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

Пример.

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

public class Test {

    int x;

    char ch;

    boolean f;

    double d;

    // конкструтор   

    public Test()

    {

        System.out.println("x=" + x);

        System.out.println("ch=" + ch);

        System.out.println("f=" + f);

        System.out.println("d=" + d);

    }

  }

 

 

На экран будет выведено:

x=0

ch=

f=false

d=0.0

 

 Далее, добавим в класс метод Metod(), объявим в нем переменную i примитивного типа также без инициализации - это локальная переменая  и попробуем вывести ее значение.   

 

public class Test {
int x;
char ch;
boolean f;
double d;
// конкструтор
public Test()
{
System.out.println("x=" + x);
System.out.println("ch=" + ch);
System.out.println("f=" + f);
System.out.println("d=" + d);
}
// добавим некоторый метод
public void Metod()
{
int i; //локальная переменная не инициализирована
System.out.println("i=" + i); // компилятор выдаст ошибку
}
}

 

Компилятор выдаст ошибку: «variable i might not have been initialized» - переменная i, возможно, не была инициализирована и предложит выполнить ее инициализацию.

 

Логический тип

В Java переменные логического типа задаются с помощью ключевого слова boolean и могут иметь лишь одно из двух значений: true или false.

Тип boolean занимает в памяти 8 бит. 

В Java в отличие от C и C++ константа true не равна 1, а константа false не равна 0.

B Java значения true и false могут быть присвоены только тем переменным, которые объявлены как boolean, или использоваться в выражениях с булевскими операциями. Например, логическое выражение, которое должно быть истинно, если значение х попадает в интервал     [x1, x2], должно быть записано следующим образом:

х>=x1 && х<=x2

Чтобы сделать  выражение хорошо читаемым, используют скобки

(х>=x1) && (х<=x2)

Вот пример.

boolean isInRange;

int x1= 1;

int x2=5;

int x=3;

isInRange = x>x1 && x<x2;

System.out.println("Внутри диапазона: " +isInRange);

 

Будет выведено:
Внутри диапазона: true

 

Целочисленный тип

Целые типы различаются по размеру отведенной для них памяти:

  • byte - 8-разрядное целое число
  • short - 16-разрядное целое число
  • int - 32-разрядное целое число
  • long - 64-разрядное целое число
  • char - 16-разрядное беззнаковое целое, представляющее собой символ  UTF-16 (буквы и цифры)
Тип Размер (бит) битах Минимальное значение Максимальное значение

byte

8 (знаковое)

-128

127

short

16(знаковое)

-32768

32767

int

32(знаковое)

-2147483648

2147483647

long

64(знаковое)

-922372036854775808

922372036854775807

char

16(без знаковое)

0

65536

 

Символьный тип

Для работы с символами в Java используется тип данных char, в котором символ представлен в 16-битным значением в Unicode-таблице.

Unicode (Юникод) - это стандарт кодирования символов, который позволяет предоставить знаки всех языков мира. Каждый символ представлен двумя байтами, которые позволяют  хранить в себе число от нуля до 65535, что и позволяет использовать 65536 различных символов.

Диапазон допустимых значений этого типа от 0 до 65536. Не существует отрицательных значений типа char. Над переменными символьного типа допустимо выполнение арифметических операций.

Вот небольшой пример.

char ch1, ch2, ch3, ch4;

int kod;

int sum;

ch1 = 'A';     // Записываем в переменную ch1 символ A

ch2 = 65;      // переменной ch2 также присваивается символ A. Его Unicode код  равен 65  

ch3 = 'B';     // Записываем в переменную ch3 символ B, его код 66

ch4 = 'C';     // Записываем в переменную ch3 символ C, его код 67

kod=(int)ch1;  //получаем код переменной по символу из Unicode-таблицы  

System.out.println(ch1 + " " + ch2 + " "+ kod ); //будет   выведено:   A   A   65

// находим сумму

sum =ch2 + ch3 + ch4;           // выполняется сложение кодов: 65 + 66 + 67 = 198

System.out.println(sum);        //будет выведено  198

//по коду найдем символ

System.out.println((char)sum);  //будет выведен символ E 

 

 

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

boolean f;

   f= ch3>ch1;              // код  67 > 65

   System.out.println(f);   //будет выведено   true

 

Переменная f примет значение true потому, что  символ ch1 имеет код меньше чем символ ch3: ch1 расположен по алфавиту и в  Unicode-таблице также раньше символа ch3.

Вещественные типы

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

Тип Разрядность (бит) Диапазон Точность
float 32 3,4e-38 < … < 3,4e38 7-8 цифр
double 64 1,7e-308 < …< 1,7e308 17 цифр

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

Формат записи числа с фиксированной точкой совпадает с обычной математической записью десятичного числа с дробной частью. Дробная часть отделяется от целой части с помощью точки, например

34.5, -4.0, 77.001, 100.56

Формат записи с плавающей точкой применяется при записи очень больших или очень малых чисел. В этом формате число, стоящее перед символом «E», умножается на число 10 в степени, указанной после символа «E». Вот примеры.

Запись с плавающей точкой Математическая запись
1E-4 1*10-4
3.4574E+3 3.4574*10+3
4.51E+1 4.51*10+1

 

Примеры чисел с плавающей точкой:

Число Запись на Java
0,0001 1E-4
3457,4 34574E-1
  double vx =1E-4;
double vy =7.94E+4;
double vz = 34574E-1;
System.out.println(vx);   // будетвыведено 1.0E-4
System.out.println(vy);   // будетвыведено 79400.0
System.out.println(vz);   // будетвыведено 3457.4

 

Стандартные математические функции возвращают тип double, численные константы по умолчанию также  определены как double. Чтобы задать число типа float, необходимо добавить в его конец символ "f" или символ "F".

Примеры объявления переменных с плавающей точкой:

 float x = 3.5f;
float y = 4.94E+1f;
double z = 1.0.

 

 

Ссылочный тип  данных.  (Reference)

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

Ссылочные типы  в языке Java включают:

    • Массивы
    • Классы
    • Интерфейсы
    • Перечисления
Свойства ссылочного типа данных:
    • При выполнении операции присваивания в ссылочную переменную заносится адрес данных, а не сами данные.
    • Если ссылочной переменной не присвоено значение - адрес данных, в ней хранится null.
    • null – это зарезервированное слово, в котором храниться нулевой адрес. Любому ссылочному типу может быть присвоено значение null. Поскольку null хранит адрес, то естественно  мы не можем присвоить null переменной любого примитивного типа:  byte, short, int, long, float, double, char и boolean.
    • Все ссылочные переменные изначально инициализируются значением null.
    • Непосредственного доступа к адресу, хранящемуся в ссылочных переменных нет.
    • Ссылки можно присваивать друг другу, если они совместимы по типам, а также присваивать значение null. При этом из одной ссылочной переменной в другую копируется адрес.
    • Ссылочные переменные можно сравнивать на равенство, в том числе на равенство null. При этом сравниваются не данные, а их адреса, хранящиеся в ссылочных переменных.

Различие примитивных и ссылочных типов данных

Возьмем примитивный тип int и рассмотрим следующий код:

int a=5;    // объявляем первую переменную и инициализируем ее

int b=a;    // объявляем вторую переменную, далее присваиваем b=a.

            //В этой операции выполняется копирование значения ячейки а в ячейку b

a=3;        // меняем значение первой переменной

// выводим значение переменной a

System.out.println(“a= “ + a);         // будетвыведено  a= 3

// выводим значение переменной b

System.out.println(“b= “ + b);         // будет выведено b= 5

 

       Из данного примера следует, что при выполнении операции присвоения для переменных, имеющих примитивный тип, выполняется копирование данных из одной ячейки памяти в другую.

      Выполним операцию присвоения (копирования) для ссылочных переменных. Для этого напишем простой класс Point -точка на плоскости, имеющая координаты x и y.

public static class Point{

    public   int x; //координататочки x

    public   inty; //координата тоски y

//конструктор

Point(int X, int Y) {

    x=X;

    y=Y;

  }

}

 

Создадим несколько объектов класса Point  и выполним операцию присвоения. 

//cоздаем объект – первую точку
//при выполнении данной операции будет
//создана переменная объектного типа p1,
//которая будет содержать адрес объекта
Point p1 = new Point(1,1);

//создаем переменную p2 и выполняем
//операцию присваивания
Point p2=p1;

//меняем координату x первого объекта
p1.x=7;

//выводим координаты первого и второго объекта
System.out.println("p1.x="+ p1.x);
System.out.println("p1.y="+ p1.y);
System.out.println("p2.x="+ p2.x);
System.out.println("p3.y="+ p2.y);
System.out.println("---------");
//создаем переменную p3 и выполняем
Point p3 = null;

//создаем третий объект
p3= new Point(3,3);

//выполняем операцию присваивания
//теперь все переменные указывают на
//третий объект

p2=p3;
p1=p3;
System.out.println("p3.x="+ p3.x);
System.out.println("p3.y="+ p3.y);
//выводим коорлинаты
System.out.println("---------");
System.out.println("p1.x="+ p1.x);
System.out.println("p1.y="+ p1.y);
System.out.println("p2.x="+ p2.x);
System.out.println("p3.y="+ p2.y);
System.out.println("---------");

буудет выведено:

p1.x=7
p1.y=1
p2.x=7
p3.y=1
---------
p3.x=3
p3.y=3
---------
p1.x=3
p1.y=3
p2.x=3
p3.y=3
---------

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