⬆️ ⬇️

Var and val in java?

From the translator : the author of this note is Stephen Colebourne , the author of the Joda Time library and the Java Time API .




Should I add output types of local variables in Java? Right now, the Java team asked this question.



Output types of local variables



JEP-286 offers to add type deduction of local variables using a new pseudo-keyword (interpreted as “reserved type name”):



Explicitly specifying the type of local variables is often not necessary. By allowing developers to omit it, we want to simplify Java development by reducing the required number of formalities, but without sacrificing static typing.


There are several options for keywords:

')



The current implementation strategy implies that the final keyword will still be valid before any of these options, with the result that immutable variables can be declared in any of these ways:





Therefore, in fact the choice is reduced to one of the following combinations:





In general, this opportunity does not excite me, and I am not sure that Java will get better from this. Of course, when working in IDE, the lack of type information will be smoothed out. However, I believe that in many cases it will make it difficult to review the code, since it is usually done without the help of the IDE. It should also be noted that the C # programming agreement does not recommend excessive use of this feature:

Do not use var when the type of the expression to the right of the assignment is not obvious.

Do not rely on the name of a variable when determining its type. It may not be true.


Despite the foregoing, I suspect that I have little chance of stopping the implementation of this improvement. Therefore, the rest of the article is devoted to how to choose the correct option from the proposed ones.



Best for Java



When this improvement was announced, adherents of Scala and Kotlin, naturally, began to advise using var and val . However, although it is always useful to study the experience of predecessors, this does not mean that for Java this option would be ideal.



The main reason that the best option for Java may be different is history. In Skala and Kotlin, this possibility was from the very beginning, but not in Java. And I want to demonstrate why, for historical reasons, using val or let not suitable for Java.



Consider the following code:

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


The output of local variable types would work fine here. But suppose that the type of a variable in one of the lines is not clear when reading the code and we decided to specify it explicitly, following the C # recommendations:

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


Everything is fine, you say. But what if this code is written by a command, where do the agreements imply explicitly label local variables with the word 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; } 


Suddenly there was confusion. In some places, the word final used to designate an immutable variable, and in other places the word val . It is this mixture that spoils everything and at the same time such a problem is not worth it in Skala and Kotlin.



(Perhaps you are not using final for each local variable? I am not using it. But I know that this is a very reasonable standard, invented to improve development security and reduce errors.)



But an alternative:

 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; } 


For java this is much more consistent. The word final continues to be the ubiquitous mechanism for defining an immutable variable. And if you, like me, do not consider it necessary to sign final everywhere, you simply delete it:

 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; } 


I understand what objections many readers will have in this place. They say there should be two new “keywords”, one for mutable and one for immutable local variables, and both should be the same length (or even the word for mutable should be longer) to encourage people to use the immutable version more often.



But Java is not so simple. The word final existed for many years. If you close your eyes to this fact, the code will turn into an ugly and inconsistent mess.



Conclusion



I personally do not like the derivation of local variable types at all. But if we still decided to do it, it is necessary that it fits well with the existing language.



My position is that val and let not suitable for Java, because the word final already exists and it has an understandable meaning. Although the variant with var and final var not perfect, I believe that this is the only one of the proposed combinations that fits an existing language.

Source: https://habr.com/ru/post/280188/



All Articles