Система типов и проверка аргументов.



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



Первый вопрос: когда происходит проверка? В зависимости от ответа типизация может быть:

🔸Cтатической

🔸Динамической



При статической тип указателя навсегда закрепляется при создании:

String str;

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

Отлавливается много ошибок.

Быстро работает в рантайме.

Предсказуемое поведение.

Легко тестировать.



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

value = "а"

value = 4

Аргументы проверяются во время вызова метода. Такие программы в разы короче и легко адаптируются к изменениям.



Java является языком со статической типизацией.



Второй вопрос, на который отвечает система типов: что делать, если метод принимает тип А, но приходит объект типа Б? Можно:

▪️Бросить ошибку.

▪️Преобразовать Б в тип А.



У языка сильная типизация, если допустимо мало преобразований. Если много, то типизация слабая. Речь идёт о неявных преобразованиях, которые делает компилятор или исполняющая среда.

Пример: 5L + 1

Язык Ruby не разрешает складывать числа разных типов, а java приведёт единицу к типу long и выполнит сложение. Выражение

5 + true

в java вызовет ошибку компиляции. JavaScript спокойно переведёт true в единицу.

Компилятор java может перевести:

- подкласс в суперкласс

- long в int и наоборот

- int в Integer и наоборот

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



Вернёмся к вопросу перед постом. Метод id ожидает аргумент типа Long, а передаётся примитивный int. В правилах преобразований нет перехода int → Long, поэтому будет ошибка компиляции. Достичь цели можно в 2 шага:

int → long

long → Long

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

(long) intValue