All good Java developers I know make all local variables final to force better code.
All good Java developers I know make all local variables final to force better code.
Person p = ....
p = doSomething(p)
...
p = doSomethingElse(p)
is hard to reason about when it should be Person p = ....
... lots of code
Person updated = doSomething(p)
... lots of code
doSomethingElse(updated)
Which is easier to read and understand. So you might have had bugs that would have been prevented with final, but you didn't attribute to final.You shouldn't be able to doSomethingElse(p) when you actually mean to doSomethingElse(updated).
What would help is splitting the function up so that you don't have multiple named variables representing multiple versions of the same thing in the same scope:
Person doSomethingAndDots() {
Person p = doSomething(...)
...
return p
}
main() {
doSomethingElse(doSomethingAndDots())
}That is to ease the pain of unwrapping nested types and error-checking intermediate steps so you don't have to come up with new names for each intermediate.
In the codebase I work on most, all variables that can be marked final are marked final. That means that whenever I see a non-final variable, I know that something tricky is happening and I need to be extra careful in reading the code.
The Optional class is typical of the halfassery that has accompanied many improvements to Java over the years. From java.util.logging to generics to streams, I'm invariably irritated by compromises particularly as they've decided that maintaining backward compatibility is now a secondary concern.
I've run out of patience in the direction Java has taken and I've been a user since 1.0.4 - I'm going to try Kotlin for my next project.
It also works in the opposite direction: a Java parameter or return value annotated as @Nullable (doesn't have to be intellij's, the Kotlin compiler understands several annotation libraries) will appear as a nullable reference to Kotlin code, and a @NotNull or @Nonnull annotation makes it appear as a non-nullable reference.
return Optional.ofNullable(applications).orElseThrow(NullPointerException::new);
return Optional.ofNullable(applications).orElse(new Application());
var i = 0;
final var i = 0;
int i = 0;
final int i = 0;
val i = 0;
One of the options there is a very odd one. And if there was "val", would "final var" be disallowed?In Scala, where var/val both exist, each time you declare a variable you are forced to think about its mutability. But if you only have "var", with the _option_ of tacking "final" to it, then a programmer can simply forget to make that decision, because the language allowed them to.
`Simple<List<Map<String, Demo>, OtherList<Map<Int, String>>` is a little bit painful.
I use scala and basically most often at least public Methods should (in scala you can omit even that, however some functional libraries need a return type) have a explicit type, which most often is enough.
So instead of typing:
AbstractConcreteFactoryFactory factory = new AbstractConcreteFactoryFactory();
You can just type it only once: var factory = new AbstractConcreteFactoryFactory(); var p = new Person();
p = 1234; // This will trigger a compile time errorC# is a huge breath of fresh air compared to java largely because of useful type inference. It's easy to make compilers do more work now.
Rust is doing type inference with drastically stronger types, for example.