DEV Community

loading...

Discussion on: Java 15 in 2020: Reasons to *not* use Java?

Collapse
michelemauro profile image
michelemauro

Well, immutability is just a final away. Maybe you meant "lack of immutability as default"?
What do you mean as "first class citizen"?

Collapse
tim_klug profile image
Tim Klug

Even with final, a List is still mutable. I like the idea to explicitly make things mutable and have immutable types per default. Just the noise of the verbosity code.
I normally end up having a large code base in a class, to prevent the class from being abused. So the next developer needs to read all the code again, ...

Thread Thread
michelemauro profile image
michelemauro

There are ways to cope with that. But if you are really hurt by the verbosity yes, you can only get that short in Java. There are alternatives, even on the JVM.

Thread Thread
tim_klug profile image
Tim Klug

On the JVM I like atm Kotlin the most. I have worked with C# and F# and now the company uses Java. But for me on the long run, I will try to focus on Kotlin.

Thread Thread
brunoborges profile image
Bruno Borges Author

But isn't this code clear, non-verbose and with an immutable list?

import java.util.*;
import static java.lang.System.out;

public class Hello {
  public static void main(String... args) {
    var a = "a";
    var b = "b";
    var c = "c";

    // immutable list
    var immutList = List.of(a, b, c);

    // create a mutable list of the strings above
    var l1 = new ArrayList<>(immutList);
    l1.add("d");

    // turn list back to immutable
    var immutList2 = Collections.unmodifiableList(l1);
    immutList2.forEach(out::println);
    immutList2.add("e"); // runtime exception
  }
}
Thread Thread
tim_klug profile image
Tim Klug

From my point of view I mostly use the of() functions to create a data structure. But while the list itself is immutable the elements are still mutable.

public class Main {

    public static void main(String[] args) {
        var a = "a";
        var b = "b";
        var c = "c";

        List.of(a, b, c)
                .forEach(it -> it = null); // mutate the data
    }
}

And I think here is the think that often ends in the NPE hell. Some people write very protective code, where everything that could be null, is checked for null. There is no concept like val from the Kotlin world.
So from what I saw in the code bases I worked with is, that some people are using something like this:


void doSomething(List<Item> items, Data someDate) {
  ...
}

When I go through those methods, they mutate some items or all of the list. Now here you need to be aware, that the list is passed by ref. So testing and complexity of the code is not super trivial anymore. So what I meant with first class citizen is the idea, that from my point of view it should be easy to not mutate a state and write pure functions and mutating the state should need much more verbosity code. But that is what I think.

Thread Thread
brunoborges profile image
Bruno Borges Author • Edited
List.of(a, b, c)
       .forEach(it -> it = null); // mutate the data

This code doesn't change the data at all. The list continues to be the same after the forEach. This code above is the same as this:

        var a = "a";
        var b = "b";
        var c = "c";

        var list = List.of(a, b, c);
        list.forEach(it -> it = null); // mutate the data
        System.out.println(list);  // prints [a, b, c]

        for(var x : list) {
          x = null;
        }
        System.out.println(list); // prints [a, b, c]

The data continues to be immutable.

Thread Thread
michelemauro profile image
michelemauro

If you need val immutability, Scala is just a few jars away, And VSCode support with Metals is getting really good.

Collapse
almostconverge profile image
Peter Ellis

Fun fact: final classes with only final fields are NOT entirely immutable.