HTML Diff
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 &lt; 10; i++){ //здесь что-то интересное происходит }<p>Здесь переменной i неявно устанавливается тип int.</p>
12 for (var i = 1; i &lt; 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>