1

In swift, it is recommended to declare a variable with let keyword if the variable does not change after initialisation. I see a lot of variables declared as let.

In java, I think the keyword final can serve the same purpose. But from my limited experience, I only see people declaring variables as final in rare circumstance e.g. PI.

Why isn't Java variable declared as final more often? Is there something I'm missing?

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
Thor
  • 9,638
  • 15
  • 62
  • 137
  • 5
    Because it is extra typing and programmers are lazy. But if you use an IDE it probably has a function to "add final where possible" automatically when you save the file. – Thilo Jul 01 '16 at 07:49
  • 1
    Because people are lazy. `final` is _required_ pre Java 8 for closures, but apart from that is rarely used. I and [Robert Simmons Jr.](http://shop.oreilly.com/product/9780596005689.do) advocate it's greater adoption. The main reason is that it does filter out some stupid typos at compile time. But as it has no effect on program running time, unlike `const` in C++, there isn't a strong enough (for many people) argument for the extra typing and code noise. – Boris the Spider Jul 01 '16 at 07:50
  • @Thilo so just like let keyword in swift, I should declare a java variable final whereever possible? – Thor Jul 01 '16 at 07:50
  • 2
    Yes, you should. It clearly marks your intent (of not wanting to change the value by accident). Every intent you communicate to the compiler helps catch errors (same argument as for `@Override` -- should probably be mandatory and/or a keyword, but now it's too late, the language is out already). – Thilo Jul 01 '16 at 07:51
  • 4
    Please note: this is not really a good question; you are basically asking about opinions. My two cent: you want to make as many of your fields (static or non-static) final; but I personally do not get into the business of putting final on method parameters or local variables. – GhostCat Jul 01 '16 at 07:51
  • Whenever I place final in front of a variable, the IDE tells me I need to initialise it in the constructors. What happen if the initialisation of this variable require some relatively complex computation which is done in a method, but once initialised it never changes? Do I have to call this computation method inside the constructor in order to initialise the variable marked with final? Is it even possible to call a method before initialisation is complete? (I have more of a swift backgroud) – Thor Jul 01 '16 at 08:03
  • If you use a variable that must be changeable why should you use the final keyword to declare it ? – RockOnGom Jul 01 '16 at 08:03
  • 1
    @Jägermeister: Well, for fields, most developers would agree that it is useful to use final. But for parameters and local variables, different developers have different opinions. The answer for this question is therefore not necessarily about opinions, but to point out that there *are* different opinions. – user140547 Jul 01 '16 at 08:11
  • @RockOnGom Generally speaking: components that rely on immutable thingies have a lot of advantages over those that allow thingies to change. Thus one should lean towards designs that work with immutable variables, fields, etc. You know, there are programming languages that kinda never allow you to change an existing entity, instead you end up creating new entities that carry "changed" values. – GhostCat Jul 01 '16 at 08:28

6 Answers6

5

see In Java, should I use “final” for parameters and locals even when I don't have to?

Basically, for fields, it is useful and also changes their concurrency properties. see Java concurrency: is final field (initialized in constructor) thread-safe?

However, for local variables and parameters, final's value is less clear. It has some semantic value, but on the other hand, it can also be noise to have

public void foo (final int x, final int y){
    try{
        final int z = x+y;
    }
    catch (final Exception z){
        final String message = "";
        throw new RuntimeException(message);
    }
}

compared to

public void foo (int x, int y){
    try{
        int z = x+y;
    }
    catch ( Exception z){
        String message = "";
        throw new RuntimeException(message);
    }
}

If you have short methods (which you usually should have), then it is obvious anyway that the variables are not being changed.

Therefore, some developers prefer using final for its semantic value, while others prefer not to use it because of its verbosity.

Community
  • 1
  • 1
user140547
  • 7,750
  • 3
  • 28
  • 80
  • "while others prefer not to use it because of its verbosity". For many people, that applies to Java as a whole :-) – Thilo Jul 01 '16 at 12:09
  • @Thilo: Well true, but since Java is already quite verbose, you don't have to make it still more verbose when not necessary :) – user140547 Jul 01 '16 at 12:21
3

Java follows the traditional C thinking style where if we are creating something(Primitive types or objects) it is a variable by default and you have to put put "final" in java and "const" in C/C++ to make it a constant. Swift is very new as compare to these languages and its goals are safe programming patterns and simplicity. If you gain further experience in Java you will know that people do use final and best practices more often. The main reason I think(as you have also mentioned) is you have limited exposure to Java.

Khurram Shehzad
  • 261
  • 3
  • 12
2

As described by Marko Topolnik here, when, initializing a variable with final in Java, "the compiler makes sure that you can initialize it only once." If it is a primitive type like int or doubles, it can ensure that the value cannot change. However, for Object (again quoting that answer), "final is only about the reference itself, and not about the contents of the referenced object." It makes no guarantees the values inside the object being referred to staying the same.

For example, I can define a List with final as follows:

final List<String> foo = new ArrayList<String>();

The above List foo cannot be initialized again but its content can be changed, i.e. it does not make foo immutable. Therefore, this make final keyword less useful.

final keyword has its place in declaring a constant value, especially if need only one instance in a class using a static keyword. Following is an example in java.util.Random.Math:

public final class Math {

    public static final double PI = 3.14159265358979323846;
Ryan M
  • 18,333
  • 31
  • 67
  • 74
Wilson
  • 11,339
  • 2
  • 29
  • 33
2

Why isn't Java variable declared as final more often? Is there something I'm missing?

What you are missing is "human nature".

Simply, the syntax of Java makes it easier NOT to add the final. And in general, people don't, because it is easier not to.

Note that the "variables are not final by default" design decision comes from Java's ancestry.


Of course, this doesn't address your implied question as to whether Java programmers should use final more often1. But that is a matter of opinion, and StackOverflow discourages opinion-based Q&A's.

1 - .... in contexts where it would be appropriate. Using final where a variable clearly needs to be mutable is counter-productive.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • This also applies to classes and methods, which some say should be `final` by default. – shmosel Jul 01 '16 at 08:05
  • Yea ... though it is a different problem. There you are dealing with the problem of abstraction breakage due to inheritance. – Stephen C Jul 01 '16 at 08:08
  • @shmosel You should declare methods `final` where possible (as long as you won't override it). Otherwise they are virtual by default and there are performance loss. – Xiaojun Chen Jul 01 '16 at 08:10
  • @StephenC could you please tell me where I could ask this kind of opinion based Q&A related to programming? – Thor Jul 01 '16 at 08:10
  • @XiaojunChen - That is incorrect. The JIT compiler deals with that. – Stephen C Jul 01 '16 at 08:10
  • Nowhere on StackExchange :-) This is not a debating society. – Stephen C Jul 01 '16 at 08:11
  • @Stephen C I think it is better to explicitly declare it than let the compiler figure it out by itself . Or by extreme rare occasion people are not using oracle JVM :-) – Xiaojun Chen Jul 01 '16 at 08:19
  • I disagree. Cluttering your code with dubious hints to the compiler is a bad idea. It makes your code less flexible, less readable, harder to maintain, etc. (Like in the bad old days when some C programmers used to over-use the `register` keyword ... until C compiler writers decided to make the compiler **ignore** the keyword!) – Stephen C Jul 01 '16 at 08:37
1

I think this is because there isn't such a "tradition" in Java.

You see, the first book I read about Swift (The Swift Programming Language 2.0 by Apple Inc.) says that every variable you create that is not mutated should be declared as a let constant.

Since The Swift Programming Language 2.0 (the book) is the official guide to Swift, almost everyone follows it. Even if people don't read that book, they will read tutorials written by people who have read that book. As a result, everyone's coding style is like that.

In contrast, the first book I read about Java (Programming with Java for Dummies), doesn't emphasize that we should use final if the value isn't gonna change. And the official documents rarely do that as well. So only a few programmers follow that rule. This resulted in the majority writes code that actually follows this rule.

In addition, You have to write 5 more characters (the word "final" plus a space) to declare a constant in Java, whereas in Swift, you don't write any extra characters (var and let have the same number of characters)! Programmers are lazy, y'know.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
1

At least based on my experience, I am told it is recommended to use final if the variable doesn't change after initiation. For primitive type, JVM will treat it as constant and do some optimisation.

Other occasions like, in Java, all methods are by default virtual unless declared final. It will also gain computation performance.

Xiaojun Chen
  • 1,222
  • 2
  • 12
  • 21