Kotlin val,var vs Java final - advantage?

I am new to Kotlin, been at it for the past week and was reading about the val/var qualifiers. I have found that val and final (from Java) are functionally equivalent and var would be a variable without having any qualifier in Java.

Isn’t the Java’s final system less verbose, as in, not required for normal variables(resulting in less code)? Couldn’t Kotlin carry forward the same convention? What is the real advantage here?

Isn’t the Java’s final system less verbose, as in, not required for normal variables(resulting in less code)?

Kotlin:

var greeting = "hello world"

Java:

String greeting = "hello world";
//or Java 10+
var greeting = "hello world";

I’m not sure how you concluded that Java is less verbose. Most of the fields declared in Kotlin code will have implicit types, so they should be on par with modern java code.

1 Like

The difference between var and val is not about functionality, but about design. There are some additional optimizations for read-only variables in JVM, but in general, it is not about that.

In kotlin “normal” property is val. Highlighting the fact that one should prefer an immutable/read-only state over a mutable. It is a subtle difference, but it greatly affects the design.

2 Likes

I see 3 reasons to prefer val over final:

  1. Verbosity. I don’t know where did you get an idea that final var is less verbose than val. For me it’s the opposite. I think you would need to elaborate on this.
  2. What @darksnake said. final feels like an additional flag or constraint for the variable. Final variable feels like a special case of a “normal” variable. On the other hand, val and var are on the same level, they are “siblings”. In Java I rarely used final, even if I always designed my code to use immutable variables. This is due to final’s verbosity and because I always felt like I need to have a good reason to mark a variable as final. In Kotlin I code “val-first” and as a result 80-90% of my variables are val.
  3. My opinion is that val and var are actually a little different things, conceptually. Remember that when used on interface/class, val really means: “there is a getter” and var means: “there is a getter and setter”. If we would use final then it would mean something like: “there is no setter” or “remove the setter” - it sounds a little odd to me.

Ahh, I think I understand your point about verbosity - you compare String foo and var foo: String.

Firstly, it seems you think mutable variables are somehow “default” or more common, so you focus on this case. This is exactly what I meant saying that Java gives you a feeling that mutable variables are “normal” ones. As a matter of fact, it is always better to prefer immutable variables - for performance and code readability.

Secondly, I think you mistook what is the real cause of this additional verbosity. This is not really val vs final. In Kotlin we are just more explicit about all kinds of definitions. In Java we need to use special keywords to define a class, enum, etc., but we don’t use any keywords for defining fields and methods - definition is implicit from the syntax. In Kotlin all definitions are explicit, so we always have to use val, var or fun. I guess this is to increase code readability (but yes, this is more verbose).

1 Like

final is more verbose than val, and there are implications for that. A language that has more verbose version of immutable variables, tend to favor mutability against immutability, ie. Java. A language that has less verbose version of immutable variables, tend to favor immutability against mutability, ie. Rust. A language like Kotlin though, makes equal emphasis on immutability and mutability.

I find that they missed the opportunity to use const and auto instead of val or var.

Then you just write const auto data = someCall() (java style, I keep forgetting kotlin style)

Now it doesn’t matter anymore if someCall returns a string, map list or even if the objects with the containers are immutable or not.

Const will just make everything immutable.

Having a keyword in front of a field is the better choice. In C it didn’t matter, so they started with a type, but as soon as there is type inference, you need some kind of keyword, even in Java.

Having this keyword there by default gives you a more consistent look:

// Java
String foo;
var bar = "xyz";

// Kotlin
var foo: String
var bar = "xyz"

I find the Kotlin way much easier to read.

In almost all cases the name of the variable and whether it is immutable is more important than the actual type, and that’s what you always see first in Kotlin.

2 Likes

Maybe I misunderstood you, but how would this work? How to make mutable objects immutable?