This might be considered a programming question, but it is concerning test code, written in Selenium plus Java, so I think this is the relevant site to post this.

When viewing other people's tests online, I sometimes find web elements added to a variable declared as final:

final WebElement element = driver.findElement(By.id("element-id"));

I'm guessing that allows for better atomization and isolation of the tests and it makes sense.

Since I haven't had problems with not declaring the variables final, are there any more reasons to do this?

  • 2
    i think using final limits the use of parallel execution . But haven't tried it myself – PDHide Oct 24 '20 at 12:58
  • 1
    Can you give a reference to such test? What is the context of using such approach? Is this a declaration inside a method or it is definition of class field? – Alexey R. Oct 24 '20 at 13:09
  • I'll provide an example on Monday. – Mate Mrše Oct 24 '20 at 15:16
  • 1
    I voted for reopening – PDHide Oct 26 '20 at 13:57
  • 2
    I would like to reiterate - ANY question related to Selenium is on topic on this site. The Selenium site was merged into this site, and part of the understanding is that any Selenium related content would be on-topic. – corsiKa Oct 27 '20 at 1:17

This is a standard programming practice intended to reduce bugs in code. As a refresher, the final modifier prevents a primitive variable or object reference variable from being reassigned. Thus, primitives are immutable, and a reference can ever point to the object it initially pointed to. (This does not affect what methods you can call, even ones that would mutate the object's internal state.)

Every IDE I've used in the past 10 years has had the ability to inspect the code in a method and deterministically apply the final modifier to a local variable that is not reassigned after it is initialized. The idea behind this is that if you wrote code, and saved it (which runs save actions that apply the final modifier) you probably don't mean to modify that variable again. If you DO intend to modify that variable, you can simply remove the modifier. Under this logic, every variable is final until someone actively decides it should not be.

As with all things programming, there are counter arguments to this. One is it clutters the code, increasing the workload on a programmer trying to read the code to maintain it. While this hasn't been my personal experience with this modifier, I know it has been with other practices for me so I don't want to dismiss this outright simply because it doesn't apply to me. The other is that if you only use it on ones that you decide should be final (as opposed to blanketing the code with final) you're sending a message to other developers that this variable should never change - that it should stand out among other variables as one you should not attempt to change.

PDHide's comment about limiting the use of parallel execution is related - final variables are eligible to be used in lambdas and parallel processing while other variables are not. Now I believe (it's been a while) the Java compiler will allow you to use a variable that is effectively final even if it is not explicitly final but then if someone decides to modify the variable before the parallel execution, the compiler can no longer say that it's effectively final and thus no longer eligible for the parallel processing and will throw a compile error. Easily fixed, but can be annoying nevertheless.

At the end of the day, you will want to have a brief conversation with your team to decide what will work best for you. The keyword has zero impact on the actual execution or efficiency, and it's all a matter of programmer productivity.

  • I am not sure you are right. Forcing variable to be final if it is not reassigned does not make much sense. Someone can extend the class or reassign it in client code. If you do not change it in your code that does not mean that people that would use your code wouldn't need to reassign it. IDEs suggest marking variables as final indeed but there are different reasons. Like using field as lock object in synchronization, etc. – Alexey R. Oct 24 '20 at 19:39
  • I have edited the answer to clarify: this only applies to inside a method i.e. local variables. For example, the code in the OP: I would not expect a web element to be an instance variable! – corsiKa Oct 24 '20 at 19:53
  • Of course, making the variable final does not make it immutable. For instance, final List objects = Arrays.asList({"a", "b"}); objecs.add("c"); is perfectly valid, but final List objects = Arrays.asList({"a", "b"}); objects = new ArraysList(); would not be. See stackoverflow.com/questions/15655012/… for more. – dzieciou Oct 25 '20 at 11:16
  • 1
    That is correct - and indeed I could foresee annotated methods on a class that indicate whether or not it mutates the object or not, and an IDE preprocessing those in conjunction with an assignment annotation that effectively does the same thing - but that's not in the language, only modifying the reference variable, which is why you see the "add final save action" in so many IDEs. I will update to clarify the answer, though, just in case people do get confused by the term. – corsiKa Oct 25 '20 at 18:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.