1

As I was progressing through my java course, I came across this exercise where I create a commissionemployee class.

public class CommissionEmployee extends Object{  //This is not required, because every class extends Object by default, and the toString method in Object is returned when printing an object.
private final String firstname;
private final String lastname;
private final String socialSecurityNumber;
private double grossSales;
private double commissionRate;

public CommissionEmployee(String firstname, String lastname, String socialSecurityNumber, double grossSales, double commissionRate){ //constructor starts here

And all the methods defined inside this class are only getFirstname(), getLastname, etc. and no set methods to alter already initialized object, and an object can be created only by passing all the variables as parameters, because there is no default constructor.

In this scenario, why was the instance variables declared as private final String? Why was private String not preferred by my course instructor? and why was grossSales and commissionRate not declared as final?

scott
  • 1,557
  • 3
  • 15
  • 31
  • 2
    In general you should set attributes private and write getters and/or setters ([Encapsulation](https://en.wikipedia.org/wiki/Encapsulation_%28computer_programming%29), there are exceptions though). For the `final` keyword... you can understand it more as a help for the reader than an assertion of the language. There are ways to change final variable (via Reflection). Also, notice that `String`s are immutable. If you have a final attribute that is an object, only the reference is final. The object itself is not `final` (i.e. you can change its attributes). – Turing85 Nov 12 '15 at 15:19
  • 1
    [This](http://stackoverflow.com/questions/18194139/make-immutable-java-object) might help – TheLostMind Nov 12 '15 at 15:22
  • Thank you @Turing85. I understood the concept of private. However, I didn't get the concept of using final in this particular context. I am just a beginner, so a good suggestion to read to underrstand this context would be great. – scott Nov 12 '15 at 15:25
  • 1
    @scott I, for my part, like the Oracle tracks. [Here](https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html) is one about class members. – Turing85 Nov 12 '15 at 15:27
  • @Turing85 -- sorry, but that's complete and total nonsense. Getters and setters break encapsulation. And your statements about final are also wrong, and the statements about immutable strings have nothing at all to do with final (immutable) references. – Software Engineer Nov 12 '15 at 15:28
  • I would actually be nice had Java all the fields `final` by default and you should explicitly declare the field as `mutable` to be able to modify it. It would greatly improve the code quality. – Tagir Valeev Nov 12 '15 at 15:29
  • @TagirValeev: And `const` similarly in C++ (although, of course, `const` and `final` are very very different beasts). But there would be a fair bit of old-source-code refactoring to do! – Bathsheba Nov 12 '15 at 15:29
  • @VinodMadyalkar Thanks Vinod, I know the concept of final, but I was wondering why it was used in this context. – scott Nov 12 '15 at 15:30

5 Answers5

3

A member declared as private final String without initialisation means that 1) that member must be set on construction and, 2) it cannot be set subsequently to refer to another string. These two things serve to increase program stability. Also, because any particular string is immutable, these fields are constant.

As for the double fields, perhaps these are allowed to change?

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • thank you @Bathsheba. So this is mainly done for program stability, eventhough it is not required to explicitly declare them as final? – scott Nov 12 '15 at 15:26
  • Member declared as final without initialization? Something wrong here! – Ele Nov 12 '15 at 15:27
  • 2
    Indeed. Professional programmers are constantly discovering methods to protect themselves from themselves. – Bathsheba Nov 12 '15 at 15:27
  • @EleazarEnrique: you can assign to a final once in a constructor if it hasn't been initialised in the class declaration. – Bathsheba Nov 12 '15 at 15:28
  • Gotcha. So I can assume it is a programmer preference. – scott Nov 12 '15 at 15:28
  • @Bathsheba Isn't "constant" what we usually call static final immutable field? – Jaroslaw Pawlak Nov 12 '15 at 15:30
  • @Bathsheba - I suspect the OPs teacher was teaching them *immutability* and ended up writing this code. Ideally, all the fields should have been marked as `final` – TheLostMind Nov 12 '15 at 15:33
  • @VinodMadyalkar The scope of the lecture was on inheritance, and this was the example chosen by the instructor. – scott Nov 12 '15 at 15:34
  • 1
    @scott - Intersting. In that case yes, I think `final` is used for more of a *good programming practice* - for the time being – TheLostMind Nov 12 '15 at 15:43
  • Thank you everyone. It makes sense now. – scott Nov 12 '15 at 15:47
2

Having the first, last and SSN as final makes those fields immutable. Think about it...when would those fields need to change? Probably never...unless you were coding an app that supported legal name changes, etc. That's why they are final. So that they cannot be changed. As for the grossSales and commissionRate, they can be changed inside of CommissionEmployee

will
  • 121
  • 1
  • 1
  • 9
  • I understood the concept of final, however, the complete code never had any set methods to alter the already created object. They why was it needed, was my doubt. – scott Nov 12 '15 at 15:32
  • Do you mean set methods for `grossSales` and `commissionRate`? – will Nov 12 '15 at 15:33
  • No, there are no set methods for firstname, lastname and social security number. So I do not see a way to change it anyway, then why was it declared final. – scott Nov 12 '15 at 15:35
  • So that's the whole point of what the example is. Those `final` fields should be set in the constructor. That's the only place they can be set. – will Nov 12 '15 at 15:36
  • Please correct me if I am wrong, but that's why we have a constructor with a fixed set of parameters, and no set methods to alter the object's data. They why is it required to declare it as final again? It's like redundant way to make it immutable right? – scott Nov 12 '15 at 15:41
  • 2
    So if those fields weren't declared as `final` then they could be changed inside the context of `CommissionEmployee` In any method, etc.. – will Nov 12 '15 at 15:43
2

Much of the purpose of the final keyword is to indicate intent. Things like firstname, lastname and socialSecurityNumber are mean not to change over the course of your program, while grossSales probably does.

final helps protect from accidentally changing it later, which is particularly useful in larger projects with multiple developers, for example you might rely on the ssn not changing and use it to build a cache for faster lookup, later on if it were not final another developer may change the ssn for some other purpose, and now your cache would break. By adding final it shows your intent that this is a thing that should not change.

GHollies
  • 86
  • 5
  • Yes, it shows intent, but so does every other keyword in java. Apart from that, this answer is just wrong -- see Brandon Heck's answer for something like the truth. – Software Engineer Nov 12 '15 at 15:29
  • @EngineerDollery his answer is correct, Brandons is not the correct one! And its an urban legend that compilers optimize much at final. Look at the byte code. That will not differ. – AlexWien Nov 12 '15 at 15:39
  • The bytecode compiler doesn't really optimize at all, so looking at the bytecode won't help in the least. It's the JIT compiler that could optimize due to such hints, and it's a lot harder to see what that's doing. – Software Engineer Nov 12 '15 at 15:52
  • @EngineerDollery if the byte codes are identical then the JIT has no chance to know that it was meant to be final. The java byte code has no final kexyword: http://stackoverflow.com/questions/6651429/java-optimizations-hotspot-dalvik-optimization-of-final-method-returning-a-co – AlexWien Nov 12 '15 at 16:27
  • If the bytecode is identical, how is it that I can find whether something is final or not via reflection? – Software Engineer Nov 12 '15 at 20:02
2

The fields firstname, lastname, and socialSecurity number are defined final such that they can only be set once, in the constructor.

grossName and commissionRate are more likely to update often, therefore they are not final.

final fields can be assigned only once, that and that only is the reason your teacher defined them final. It is wrong to asume that your teacher use the final field for compiler optimizations, as other wrong aswers asume.

It seems to serve as a self protection when the code becomes more complex, to emphasize that the asignment of that final fields can only be done once.

AlexWien
  • 28,470
  • 6
  • 53
  • 83
  • there are no set methods for firstname, lastname and social security number. So I do not see a way to change it anyway, then why was it declared final? No one would change it anyway right? – scott Nov 12 '15 at 15:42
  • You are right, but when the code would be much mor complex it can be used as a self protection, to emphasize that the fields can only be initialized once. And to protect for programming errors. However it is not very usual to do it that way. But it's not wrong. This approach is soemtimes use in Singeltons to garunatee that the asignment can only be done once. – AlexWien Nov 12 '15 at 15:44
  • Thank you @AlexWien. I can assume that as a good programming practice then. :) – scott Nov 12 '15 at 15:46
1

Final variables and methods can be better optimized by the JIT (Just-In-Time) compiler. Marking a variable or method as final tells the JIT Compiler that it does not have to worry about needing to discover overridden methods or re-reading the value pointed to by a variable.

  • 2
    As for re-reading: not so simple. In controlled context (when you inline all the calls and control all the writes in current thread) re-reading is unnecessary for any non-volatile field (final or not). In other cases you cannot trust the final as it might be modified via reflection. So final field modifier helps little for JIT optimizations. – Tagir Valeev Nov 12 '15 at 15:27
  • Sorry, I should have been more specific. You are correct that the final keyword won't prevent re-reading for Objects, but it will prevent having to re-read for primitives. – Brandon Heck Nov 12 '15 at 15:29
  • And for strings, and any other immutable object (a referenced object may be a value object (DDD) and be completely immutable in its own right, therefore may count as immutable to the JIT compiler. – Software Engineer Nov 12 '15 at 15:31
  • @TagirValeev Setting final field using reflection API - it is explicitly stated in the documentation that the change may not be visible. – Jaroslaw Pawlak Nov 12 '15 at 15:33
  • We are talking about final fields not variables and method parameters! – AlexWien Nov 12 '15 at 15:39