0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><a>#База знаний</a></p>
1
<p><a>#База знаний</a></p>
2
<ul><li>16 июл 2021</li>
2
<ul><li>16 июл 2021</li>
3
<li>0</li>
3
<li>0</li>
4
</ul><p>Разбираемся, что за var такой и в каких ситуациях он может пригодиться.</p>
4
</ul><p>Разбираемся, что за var такой и в каких ситуациях он может пригодиться.</p>
5
<p>robby mccullough / unsplash</p>
5
<p>robby mccullough / unsplash</p>
6
<p>Фулстек-разработчик. Любимый стек: Java + Angular, но в хорошей компании готова писать хоть на языке Ада.</p>
6
<p>Фулстек-разработчик. Любимый стек: Java + Angular, но в хорошей компании готова писать хоть на языке Ада.</p>
7
<p>Начиная с версии 10, в Java появилось ключевое слово var. Новая фича -<strong>local variable type inference</strong>(выведение типа локальной переменной) - не даёт переменным дополнительных возможностей. Впрочем, и ограничений на них не накладывает. Просто разработчикам не нужно теперь писать лишний код при объявлении переменных, когда их тип очевиден из контекста.</p>
7
<p>Начиная с версии 10, в Java появилось ключевое слово var. Новая фича -<strong>local variable type inference</strong>(выведение типа локальной переменной) - не даёт переменным дополнительных возможностей. Впрочем, и ограничений на них не накладывает. Просто разработчикам не нужно теперь писать лишний код при объявлении переменных, когда их тип очевиден из контекста.</p>
8
<p>Если переменной<strong>сразу же присваивается значение</strong>, для которого компилятор может однозначно понять тип. Вот три типичных ситуации, когда удобно перейти от явного указания типа к var:</p>
8
<p>Если переменной<strong>сразу же присваивается значение</strong>, для которого компилятор может однозначно понять тип. Вот три типичных ситуации, когда удобно перейти от явного указания типа к var:</p>
9
<p><strong>1. При создании нового экземпляра класса.</strong>Особенно если у этого класса длинное название.</p>
9
<p><strong>1. При создании нового экземпляра класса.</strong>Особенно если у этого класса длинное название.</p>
10
var theLongestNameYouCanEverImagine = new TheLongestNameYouCanEverImagine();<p>В этом случае компилятор "догадывается", что у переменной theLongestNameYouCanEverImagine должен быть тип TheLongestNameYouCanEverImagine.</p>
10
var theLongestNameYouCanEverImagine = new TheLongestNameYouCanEverImagine();<p>В этом случае компилятор "догадывается", что у переменной theLongestNameYouCanEverImagine должен быть тип TheLongestNameYouCanEverImagine.</p>
11
<p><strong>2. В заголовке цикла.</strong></p>
11
<p><strong>2. В заголовке цикла.</strong></p>
12
for (var i = 1; i < 10; i++){ //здесь что-то интересное происходит }<p>Здесь переменной i неявно устанавливается тип int.</p>
12
for (var i = 1; i < 10; i++){ //здесь что-то интересное происходит }<p>Здесь переменной i неявно устанавливается тип int.</p>
13
<p>Если инициализировать переменную целым числом, то по умолчанию для неё будет определён тип int. Чтобы компилятор решил иначе, нужны подсказки-постфиксы: L - для типа long, F - для float, D - для double, или явное приведение к другому типу.</p>
13
<p>Если инициализировать переменную целым числом, то по умолчанию для неё будет определён тип int. Чтобы компилятор решил иначе, нужны подсказки-постфиксы: L - для типа long, F - для float, D - для double, или явное приведение к другому типу.</p>
14
var a = 2; // тип переменной a - int var b = 2L; // тип переменной b - long var c = 2F; // тип переменной c - float var d = 2D; // тип переменной d - double var e = (short) 2; //тип переменной e - short<p><strong>3. В блоке try-with-resources.</strong></p>
14
var a = 2; // тип переменной a - int var b = 2L; // тип переменной b - long var c = 2F; // тип переменной c - float var d = 2D; // тип переменной d - double var e = (short) 2; //тип переменной e - short<p><strong>3. В блоке try-with-resources.</strong></p>
15
void copyFile(File src, File dest) throws IOException { try (var reader = new BufferedReader(new FileReader(src)); var writer = new BufferedWriter(new FileWriter(dest))) { String s; while ((s = reader.readLine()) != null) { writer.write(s); writer.newLine(); } } }<p>Тут в заголовке блока инициализируются две локальные переменные: у reader будет тип BufferedReader, у writer - BufferedWriter.</p>
15
void copyFile(File src, File dest) throws IOException { try (var reader = new BufferedReader(new FileReader(src)); var writer = new BufferedWriter(new FileWriter(dest))) { String s; while ((s = reader.readLine()) != null) { writer.write(s); writer.newLine(); } } }<p>Тут в заголовке блока инициализируются две локальные переменные: у reader будет тип BufferedReader, у writer - BufferedWriter.</p>
16
<p>Присвоить значение сразу же означает, что нельзя сначала просто дать var-переменной имя и только следующим оператором инициализировать её:</p>
16
<p>Присвоить значение сразу же означает, что нельзя сначала просто дать var-переменной имя и только следующим оператором инициализировать её:</p>
17
var x; // не скомпилируется x = 3; // не скомпилируется<p>А ещё важно не перепутать окончание оператора с концом строки. Операторы в Java не прерываются переносами строк, поэтому разрешается объявлять переменную в нескольких строках:</p>
17
var x; // не скомпилируется x = 3; // не скомпилируется<p>А ещё важно не перепутать окончание оператора с концом строки. Операторы в Java не прерываются переносами строк, поэтому разрешается объявлять переменную в нескольких строках:</p>
18
var x = 3; // отлично скомпилируется<p>Нет. На это намекает первая часть названия фичи - local variable. Ключевое слово var можно использовать только с <strong>локальными переменными</strong>, то есть переменными, которые объявлены:</p>
18
var x = 3; // отлично скомпилируется<p>Нет. На это намекает первая часть названия фичи - local variable. Ключевое слово var можно использовать только с <strong>локальными переменными</strong>, то есть переменными, которые объявлены:</p>
19
<ul><li>внутри конструкторов;</li>
19
<ul><li>внутри конструкторов;</li>
20
<li>внутри блоков инициализации;</li>
20
<li>внутри блоков инициализации;</li>
21
<li>внутри методов.</li>
21
<li>внутри методов.</li>
22
</ul><p>Например:</p>
22
</ul><p>Например:</p>
23
public class VarExample { public VarExample() { // var в конструкторе var constructorVar = "constructorVar"; } { // var в блоке инициализации var initializerVar = "initializerVar"; } void methodExample() { // var в методе var methodVar = "methodVar"; } }<p>Новый метод объявления неприменим к переменным экземпляра (instance variable) и переменным класса (статическим переменным). То есть вот такие строчки кода компилятор сочтёт ошибочными:</p>
23
public class VarExample { public VarExample() { // var в конструкторе var constructorVar = "constructorVar"; } { // var в блоке инициализации var initializerVar = "initializerVar"; } void methodExample() { // var в методе var methodVar = "methodVar"; } }<p>Новый метод объявления неприменим к переменным экземпляра (instance variable) и переменным класса (статическим переменным). То есть вот такие строчки кода компилятор сочтёт ошибочными:</p>
24
public class VarExample { var instanceVar = "instanceVar"; // не скомпилируется static var staticVar = "staticVar"; // не скомпилируется }<p>Не путайте переменные, объявленные<strong>внутри</strong>методов, и переменные -<strong>параметры</strong>методов. С первыми var использовать можно, со вторыми - нельзя.</p>
24
public class VarExample { var instanceVar = "instanceVar"; // не скомпилируется static var staticVar = "staticVar"; // не скомпилируется }<p>Не путайте переменные, объявленные<strong>внутри</strong>методов, и переменные -<strong>параметры</strong>методов. С первыми var использовать можно, со вторыми - нельзя.</p>
25
public int sum(var x, var y) { // не скомпилируется return x + y; } public int sum2and2() { // а так можно var x = 2; var y = 2; return x + y; }<p>И да, и нет. Сам по себе null не даёт компилятору никакой информации о типе - ведь такое значение может быть у любого ссылочного типа. Лучшее, что мог бы сделать компилятор в такой ситуации, - это посчитать, что новая переменная имеет тип Object. Но программистам-то обычно нужно что-то более конкретное, чем Object, - у этого типа не так уж много полезных свойств и методов, так что архитекторы Java решили, что лучше null при использовании с var просто запретить.</p>
25
public int sum(var x, var y) { // не скомпилируется return x + y; } public int sum2and2() { // а так можно var x = 2; var y = 2; return x + y; }<p>И да, и нет. Сам по себе null не даёт компилятору никакой информации о типе - ведь такое значение может быть у любого ссылочного типа. Лучшее, что мог бы сделать компилятор в такой ситуации, - это посчитать, что новая переменная имеет тип Object. Но программистам-то обычно нужно что-то более конкретное, чем Object, - у этого типа не так уж много полезных свойств и методов, так что архитекторы Java решили, что лучше null при использовании с var просто запретить.</p>
26
<p>Поэтому строка ниже не скомпилируется:</p>
26
<p>Поэтому строка ниже не скомпилируется:</p>
27
var nullVar = null; // не скомпилируется<p>Но можно оставить подсказку компилятору:</p>
27
var nullVar = null; // не скомпилируется<p>Но можно оставить подсказку компилятору:</p>
28
var nullVar = (String) null;<p>И это объявление уже допустимо. Правда, не очень понятно, зачем так делать, - проще сразу явно указать тип.</p>
28
var nullVar = (String) null;<p>И это объявление уже допустимо. Правда, не очень понятно, зачем так делать, - проще сразу явно указать тип.</p>
29
<p>Нет, так не работает. Это просто нужно запомнить: var можно использовать только с одной новой переменной за раз. А вот так нельзя:</p>
29
<p>Нет, так не работает. Это просто нужно запомнить: var можно использовать только с одной новой переменной за раз. А вот так нельзя:</p>
30
int a, var b = 3; // не скомпилируется var a = 1, b = 2; // тоже не скомпилируется var a = 1, var b = 2; // и даже так не скомпилируется int a = 3, b = 2; // да-да, так всё ещё можно<p>Да пожалуйста! При объявлении задаётся только начальное значение, и менять его никто не запрещает:</p>
30
int a, var b = 3; // не скомпилируется var a = 1, b = 2; // тоже не скомпилируется var a = 1, var b = 2; // и даже так не скомпилируется int a = 3, b = 2; // да-да, так всё ещё можно<p>Да пожалуйста! При объявлении задаётся только начальное значение, и менять его никто не запрещает:</p>
31
var s = "first value"; s = "second value";<p>Есть нюанс: ключевое слово var не отменяет правила для переменных с модификатором final. Значения final-переменных, даже введённых новомодным var, менять по-прежнему нельзя.</p>
31
var s = "first value"; s = "second value";<p>Есть нюанс: ключевое слово var не отменяет правила для переменных с модификатором final. Значения final-переменных, даже введённых новомодным var, менять по-прежнему нельзя.</p>
32
final var s = "first value"; s = "second value"; // не-не-не, вы же не просто так дописали модификатор final<p>А вот и нет. Сэкономить на названиях переменных и переиспользовать одну и ту же локальную переменную с разными типами данных не выйдет. Но самим помнить о том, у какой переменной какой тип, не придётся. У компилятора память всё равно лучше, так что он просто не позволит вам совершить такого рода ошибку:</p>
32
final var s = "first value"; s = "second value"; // не-не-не, вы же не просто так дописали модификатор final<p>А вот и нет. Сэкономить на названиях переменных и переиспользовать одну и ту же локальную переменную с разными типами данных не выйдет. Но самим помнить о том, у какой переменной какой тип, не придётся. У компилятора память всё равно лучше, так что он просто не позволит вам совершить такого рода ошибку:</p>
33
var s = "string value"; // объявили переменную с неявным типом String s = "another string value"; // присвоили другое строковое значение s = 100; // не скомпилируется: попытка присвоить строковой //переменной числовое значение<p>Не путайте Java с JavaScript: в языке JavaScript тоже есть ключевое слово var. И оно тоже используется для объявления переменных.</p>
33
var s = "string value"; // объявили переменную с неявным типом String s = "another string value"; // присвоили другое строковое значение s = 100; // не скомпилируется: попытка присвоить строковой //переменной числовое значение<p>Не путайте Java с JavaScript: в языке JavaScript тоже есть ключевое слово var. И оно тоже используется для объявления переменных.</p>
34
<p>Только JavaScript не так строг к типам, как Java. Так что можно, например, присвоить переменной строковое значение, а через пару строчек кода - числовое.</p>
34
<p>Только JavaScript не так строг к типам, как Java. Так что можно, например, присвоить переменной строковое значение, а через пару строчек кода - числовое.</p>
35
<p>Не придётся, потому что var - это не зарезервированное слово. Оно может использоваться в качестве имени переменной или даже пакета. Вот так:</p>
35
<p>Не придётся, потому что var - это не зарезервированное слово. Оно может использоваться в качестве имени переменной или даже пакета. Вот так:</p>
36
var var = "var"; // так можно<p>Правда, это не отменяет тот факт, что var - не лучшее имя для переменной. Оно не очень-то, а точнее, совсем не информативно.</p>
36
var var = "var"; // так можно<p>Правда, это не отменяет тот факт, что var - не лучшее имя для переменной. Оно не очень-то, а точнее, совсем не информативно.</p>
37
<p>Это ещё хорошо, что у вас в проекте никто не догадался так назвать класс, - вот его бы пришлось переименовывать с переходом к Java 10. Слово var нельзя использовать для именования нового типа - так не получится назвать класс, интерфейс или перечисление (enum).</p>
37
<p>Это ещё хорошо, что у вас в проекте никто не догадался так назвать класс, - вот его бы пришлось переименовывать с переходом к Java 10. Слово var нельзя использовать для именования нового типа - так не получится назвать класс, интерфейс или перечисление (enum).</p>
38
<ol><li>Ключевое слово var можно использовать при объявлении локальных переменных в конструкторах, блоках инициализации, методах.</li>
38
<ol><li>Ключевое слово var можно использовать при объявлении локальных переменных в конструкторах, блоках инициализации, методах.</li>
39
<li>С ним не получится объявить параметры метода, переменные экземпляра или переменные класса.</li>
39
<li>С ним не получится объявить параметры метода, переменные экземпляра или переменные класса.</li>
40
<li>var нужно инициализировать сразу после именования - в одном операторе. При этом можно переносить такое объявление переменной на разные строки.</li>
40
<li>var нужно инициализировать сразу после именования - в одном операторе. При этом можно переносить такое объявление переменной на разные строки.</li>
41
<li>Объявлять сразу несколько переменных с помощью var в одном операторе нельзя.</li>
41
<li>Объявлять сразу несколько переменных с помощью var в одном операторе нельзя.</li>
42
<li>Инициализировать var-переменную значением null без явного указания типа тоже нельзя.</li>
42
<li>Инициализировать var-переменную значением null без явного указания типа тоже нельзя.</li>
43
<li>Значение var-переменной в дальнейшем меняться может, а вот тип - нет.</li>
43
<li>Значение var-переменной в дальнейшем меняться может, а вот тип - нет.</li>
44
<li>var допустимо использовать в качестве названия переменной, но нельзя так именовать тип: класс, интерфейс или перечисление.</li>
44
<li>var допустимо использовать в качестве названия переменной, но нельзя так именовать тип: класс, интерфейс или перечисление.</li>
45
</ol><p>Чтобы ещё лучше разобраться с var, изучите это<a>руководство</a>. В нём собраны советы по использованию local variable type inference "из первых рук" - от сотрудника Oracle.</p>
45
</ol><p>Чтобы ещё лучше разобраться с var, изучите это<a>руководство</a>. В нём собраны советы по использованию local variable type inference "из первых рук" - от сотрудника Oracle.</p>
46
<p>А если хотите больше узнать о языке Java в целом, приходите на наш курс "<a>Профессия Java-разработчик</a>". Вы научитесь программировать на самом востребованном языке, а мы поможем с трудоустройством.</p>
46
<p>А если хотите больше узнать о языке Java в целом, приходите на наш курс "<a>Профессия Java-разработчик</a>". Вы научитесь программировать на самом востребованном языке, а мы поможем с трудоустройством.</p>
47
<a>Научитесь: Профессия Java-разработчик + ИИ Узнать больше</a>
47
<a>Научитесь: Профессия Java-разработчик + ИИ Узнать больше</a>