Java var что это

Java var что это

In JDK 10 and later, you can declare local variables with non-null initializers with the var identifier, which can help you write code that’s easier to read.

Consider the following example, which seems redundant and is hard to read:

URL url = new URL("http://www.oracle.com/"); URLConnection conn = url.openConnection(); Reader reader = new BufferedReader( new InputStreamReader(conn.getInputStream()));

You can rewrite this example by declaring the local variables with the var identifier. The type of the variables are inferred from the context:

var url = new URL("http://www.oracle.com/"); var conn = url.openConnection(); var reader = new BufferedReader( new InputStreamReader(conn.getInputStream()));

var is a reserved type name, not a keyword, which means that existing code that uses var as a variable, method, or package name is not affected. However, code that uses var as a class or interface name is affected and the class or interface needs to be renamed.

var can be used for the following types of variables:

    Local variable declarations with initializers:

var list = new ArrayList(); // infers ArrayList var stream = list.stream(); // infers Stream var path = Paths.get(fileName); // infers Path var bytes = Files.readAllBytes(path); // infers bytes[] 
List myList = Arrays.asList("a", "b", "c"); for (var element : myList) // infers String
for (var counter = 0; counter < 10; counter++) // infers int
try (var input = new FileInputStream("validation.txt")) // infers FileInputStream 

In JDK 11 and later, you can declare each formal parameter of an implicitly typed lambda expression with the var identifier:

As a result, the syntax of a formal parameter declaration in an implicitly typed lambda expression is consistent with the syntax of a local variable declaration; applying the var identifier to each formal parameter in an implicitly typed lambda expression has the same effect as not using var at all. You cannot mix inferred formal parameters and var -declared formal parameters in implicitly typed lambda expressions nor can you mix var -declared formal parameters and manifest types in explicitly typed lambda expressions. The following examples are not permitted:

(var x, y) -> x.process(y) // Cannot mix var and inferred formal parameters // in implicitly typed lambda expressions (var x, int y) -> x.process(y) // Cannot mix var and manifest types // in explicitly typed lambda expressions

Local Variable Type Inference Style Guidelines

Local variable declarations can make code more readable by eliminating redundant information. However, it can also make code less readable by omitting useful information. Consequently, use this feature with judgment; no strict rule exists about when it should and shouldn't be used.

Local variable declarations don't exist in isolation; the surrounding code can affect or even overwhelm the effects of var declarations. Local Variable Type Inference: Style Guidelines examines the impact that surrounding code has on var declarations, explains tradeoffs between explicit and implicit type declarations, and provides guidelines for the effective use of var declarations.

Источник

Var и val в Java?

От переводчика: автор этой заметки — Stephen Colebourne, автор библиотеки Joda Time и Java Time API.

Следует ли добавить вывод типов локальных переменных в Java? Как раз сейчас команда разработчиков языка Java задалась этим вопросом.

Вывод типов локальных переменных

JEP-286 предлагает добавить вывод типов локальных переменных, используя новое псевдоключевое слово (интерпретируемое как «зарезервированное наименование типа»):

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

Предлагается несколько вариантов ключевых слов:

  • var — для изменяемых локальных переменных
  • val — для неизменяемых (final) локальных переменных
  • let — для неизменяемых (final) локальных переменных
  • auto — этот вариант давайте не будем рассматривать, ладно?
  • final var — превращает изменяемую локальную переменную в неизменяемую
  • final val — здесь модификатор final избыточен и ничего не меняет
  • final let — здесь модификатор final избыточен и ничего не меняет
  • var и final var
  • var и val , но final var и final val допустимы
  • var и let , но final var и final let допустимы

Не используйте var , когда тип выражения справа от присваивания не является очевидным.
Не полагайтесь на имя переменной при определении её типа. Оно может не соответствовать истине.

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

Наилучший вариант для Java

Когда было объявлено об этом улучшении, приверженцы Скалы и Котлина, естественно, стали советовать использовать var и val . Однако хотя изучить опыт предшественников всегда полезно, это не означает, что для Java такой вариант будет идеален.

Главная причина того, что наилучший вариант для Java может быть другим, — это история. В Скале и Котлине эта возможность была с самого начала, а в Java — нет. И я хочу продемонстрировать, почему из-за исторических причин использование val или let не подходит для Java.

public double parSpread(SwapLeg leg) < Currency ccyLeg = leg.getCurrency(); Money convertedPv = presentValue(swap, ccyLeg); double pvbp = legPricer.pvbp(leg, provider); return -convertedPv.getAmount() / pvbp; >

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

public double parSpread(SwapLeg leg) < val ccyLeg = leg.getCurrency(); Money convertedPv = presentValue(swap, ccyLeg); val pvbp = legPricer.pvbp(leg, provider); return -convertedPv.getAmount() / pvbp; >

Всё прекрасно, скажете вы. Но что если этот код пишет команда, где соглашения подразумевают явно помечать локальные переменные словом final ?

public double parSpread(final SwapLeg leg) < val ccyLeg = leg.getCurrency(); final Money convertedPv = presentValue(swap, ccyLeg); val pvbp = legPricer.pvbp(leg, provider); return -convertedPv.getAmount() / pvbp; >

Внезапно получилась путаница. В одних местах для обозначения неизменяемой переменной используется слово final , а в других местах — слово val . Именно это смешение всё портит и при этом такой проблемы не стоит в Скале и Котлине.

(Возможно, вы не используете final для каждой локальной переменной? Я вот не использую. Но я знаю, что это вполне разумный стандарт, придуманный для улучшения безопасности разработки и уменьшения ошибок.)

А вот альтернативный вариант:

public double parSpread(final SwapLeg leg) < final var ccyLeg = leg.getCurrency(); final Money convertedPv = presentValue(swap, ccyLeg); final var pvbp = legPricer.pvbp(leg, provider); return -convertedPv.getAmount() / pvbp; >

Для Java это гораздо более последовательно. Слово final продолжает оставаться повсеместным механизмом для обозначения неизменяемой переменной. А если вы, как и я, не считаете необходимым везде подписывать final , вы просто удаляете его:

public double parSpread(final SwapLeg leg) < var ccyLeg = leg.getCurrency(); Money convertedPv = presentValue(swap, ccyLeg); var pvbp = legPricer.pvbp(leg, provider); return -convertedPv.getAmount() / pvbp; >

Я понимаю, какие возражения возникнут у многих читателей в этом месте. Мол, должно быть два новых «ключевых слова», одно для изменяемых и одно для неизменяемых локальных переменных и оба должны быть одинаковой длины (или даже слово для изменяемых должно быть длиннее), чтобы подталкивать людей чаще использовать неизменяемую версию.

Но в Java не всё так просто. Слово final существует многие годы. Если закрыть глаза на этот факт, код превратится в некрасивое и непоследовательное месиво.

Вывод

Мне лично вывод типов локальных переменных не нравится вообще. Но если мы всё-таки решили его делать, надо, чтобы он хорошо вписывался в существующий язык.

Моя позиция заключается в том, что val и let не подходят для Java, потому что уже существует слово final и оно имеет вполне понятный смысл. Хотя вариант с var и final var не идеален, я считаю, что это единственная из предложенных комбинаций, которая подходит уже существующему языку.

Источник

Читайте также:  Java truststore password default
Оцените статью