• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

Why final objects and why not?

 
Greenhorn
Posts: 28
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What I understand is the when we declare object as a final its value would not be changed. On the other hand, if we declare it without final then we can change its value. But in which case we need to change the value of an object created of class! For example, why do I need to do the following:

Person person = New Person();

person = New Person();
 
Marshal
Posts: 80111
414
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sami radwan wrote:What I understand is the when we declare object as a final its value would not be changed. . . .

There is no such thing as a final object, but only a final reference to an object. That means the reference can only point to that one object and the reference cannot be changed. It does not however mean you can't change the state of that object. Only design of its originating class can prevent an object from changing its state: make that object immutable.That code will change the object pointed to by that reference (or it will whenever you correct the syntax error).That code will attract the attention of the compiler and line 3 will fail to compile.
 
Sami radwan
Greenhorn
Posts: 28
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Logically all reference to objects should be final, right? why would I want to make it changeable?
 
Bartender
Posts: 15737
368
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please do not quote entire posts unnecessarily, it makes the topic harder to read. I've removed the quote from your post.

Why do you say all references should be final? While it's true that in the majority of cases, a local variable doesn't need to hold a different reference than the one that was initially assigned to it, there are plenty of cases where you might want to reuse a variable to reference different objects over time. For instance, here is an algorithm that searches for a specific node in a binary search tree without using recursion:

In the code above, the node variable is assigned a different reference whenever the currently referenced node isn't the node we are looking for.
 
Sami radwan
Greenhorn
Posts: 28
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I see. But that seems to be an advanced topic for a beginner. So as beginner all my objects should be declared final? For example, In Kotlin language I see most tutorials when they creating objects they use val not var which means that the reference is final even in introductory tutorials.

 
Rancher
Posts: 5090
82
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're talking about final variables, not final objects. A good general rule for beginners (and everyone) is to make variables final (or val in Kotlin and Scala) unless there is a specific reason they can't be.  There are valid reasons for variables to be non-final - but whenever you declare a variable, ask yourself if you can make it final.  If you're not sure, make it final anyway, and see if you can make the code work.  If you can't make the code work without removing the final, then remove the final.  There's no shame in using non-final variables, but make sure they're actually necessary.
 
Rancher
Posts: 326
14
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Before talking about final reference vs non-final, regular reference it's important to understand the concept of mutable objects vs immutable objects.

String is immutable: Every method returns a new, different object.
A List, however, is mutable as its methods change its inner state.

All combinations are valid:
- non-final reference with mutable object
- final reference with mutable object
- non-final reference with immutable object
- final reference with immutable object

It depends on the context which to use.

For example: Although it does happen from time to time it's rather rare for a person to change the first name. So a common design for a class representing a person mostly will have it as final. Or even better: The date of birth which for sure will never change. On the other side a change of the last name is common due to marriage and divorce. So it can be non-final. Same for many other properties.
An example of a final mutable objects could be a list of friends: The content of what's in the list may change but it doesn't make much sense to replace the list itself (rather it would be a nested collection).
 
lowercase baba
Posts: 13091
67
Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sami radwan wrote:all my objects should be declared final?


It's confusing. I had a hard time as a beginner with this concept.  When you have a line like:

Person person = New Person();

there are two things create.  "New Person()" creates a Person object somewhere off in memory.  "Person person" creates a reference to an object of type Person.

I think of it as the reference being a card in a rolodex, where you write down the address of a house.  And the Person object is the house itself.  If you make your "person" reference final, you are writing the address in ink - it cannot be changed later.  That's not to say you can't go to the house the address points to and paint it a new color...
 
Sami radwan
Greenhorn
Posts: 28
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

fred wrote: If you make your "person" reference final, you are writing the address in ink - it cannot be changed later.  That's not to say you can't go to the house the address points to and paint it a new color...



This is great. But the question is why would I write it in ink? why not pencil?
 
Mike Simmons
Rancher
Posts: 5090
82
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, one limitation of that analogy is that if you write something in pen, it's written in pen, and you can't easily change what has already been written.  If you declare a variable final, and you later decide to delete the word final, it's easy, and the code will still work.  So the cost of switching is relatively low.

Why, then, should we prefer to use final variables when possible?  Two main reasons.  The first is to make our code simpler to understand.  If I'm looking at unfamiliar code, I'm usually trying to understand what data is being processed - which things are changing, what parts are new, and what remains unchanged.  So the moment any variable is marked final, I know it's not going to change once it's been assigned.  That makes it easier to understand and think about - I don't need to pay as much attention to what happens to that bit of data, because it's not changing.  I can focus that attention on something more important.  But if none of the variables are marked final, I have to spend more time figuring out what each one does.  Quite simply, marking things final makes them simpler to understand.  Which is good - when possible.

The second reason is for thread safety.  If you're writing code where different threads can modify data simultaneously, it can get very complicated to figure out what's going on, and some very strange errors can occur.  So it's frequently advantageous to minimize the risk of this occurring by using immutable objects - briefly, where not just one variable is final, but all the fields in the object are final - and any other objects they refer to are also immutable.  You could say this is a special case of my first reason - it minimizes complexity and reduces the chance of errors.
 
Stephan van Hulst
Bartender
Posts: 15737
368
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's basically an assertion about your program. You're saying: "I don't expect this value to change, so prevent the application from compiling if somebody writes code that changes the value". It's there to help you avoid mistakes.

For local variables, it's mostly a matter of taste. I don't like applying the final keyword to local variables because it makes the application unnecessarily wordy, for minimal benefit.

For fields, it's a huge help. Making fields final will make it much easier to write immutable types, which are essential for designing code with as few bugs as possible. It also causes the compiler to check that you've assigned a definite value to the field before the constructor call completes. Finally, final fields make some guarantees that are good when writing thread-safe types.
 
Campbell Ritchie
Marshal
Posts: 80111
414
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sami radwan wrote:. . . But that seems to be an advanced topic for a beginner. . . .

Really? I was taught object‑oriented programming without using final variables as a beginner. I had the good fortune to be taught be somebody who understood objects.

In Kotlin language I see most tutorials . . .

Please tell us where those tutorials are. I have seen few tutorials on YouTube that I have thought are really good.
 
Mike Simmons
Rancher
Posts: 5090
82
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:For local variables, it's mostly a matter of taste. I don't like applying the final keyword to local variables because it makes the application unnecessarily wordy, for minimal benefit.


I agree with this in general.  I would draw a further distinction: for local variables in well-written, clear and concise code, adding the final modifier is an unnecessary distraction.  For local variables in a long, messy method that I can't easily understand - that's different.  When I'm trying to understand the code in preparation to refactor it to something more easily understood, then adding final everywhere I can is a useful first step.  Any errors I encounter help me learn how the data is being processed.  Then I would try to use this understanding to better organize the method, usually extracting new methods so that each individual method can be shorter and simpler.  Once a method looks simple enough, then I am happy to drop the final.

Of course, in languages like Kotlin and Scala, there is no added effort to write (or read) "val" rather than "var" - so in that case, sure, use val everywhere you can.
 
Saloon Keeper
Posts: 28410
210
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:
For local variables, it's mostly a matter of taste. I don't like applying the final keyword to local variables because it makes the application unnecessarily wordy, for minimal benefit.



One word:

antibugging.

There was an old adage back when Fortran and COBOL were the primary languages: "Constants - aren't, variables - won't".

Those languages (and C) didn't support immutable symbolic values (manifest constants) at the language level, and many a poor programmer suffered because of it.

By adding a "const" or "final" feature to the language repertoire, it became possible to at least eliminate the first part of that adage.

You can say that in a limited scope, "final" is unnecessarily wordy, but I get bombed routinely by simpler errors than that. It's cheap insurance. Especially since Eclipse, at least has several stock multi-word declaration templates pre-installed, so it can be as simple to type as 2 characters plus control-space.

In the period between the old stupid compilers and today's heavily optimizing compilers, having "const" also meant that the compiler had a useful optimization hint. Nowadays the code analysis on a compiler can generally determine whether it can optimize a variable as a constant. But one very important exception exists, and that is externally-visible constant values. Since the compiler can only optimize at compile-time, it cannot predict what some other class might attempt to do with a variable not explicitly declared final.

Also note that Java doesn't use "const". "final" is not quite the same thing.
 
Campbell Ritchie
Marshal
Posts: 80111
414
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:. . . "final" is unnecessarily wordy . . .

Java® tends to be a very wordy language anyway. Just one of those things we need to get used to.

Also note that Java doesn't use "const". "final" is not quite the same thing.

No, final prevents reassignment, but it is different when applied to classes or methods. And const can be used to prevent the contents of a pointer changing, but there is no mechanism to convert a mutable reference type to immutable. I know some people will disagree with me, but I think that is as it should be.
 
Sheriff
Posts: 28346
97
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:No, final prevents reassignment, but it is different when applied to classes or methods. And const can be used to prevent the contents of a pointer changing, but there is no mechanism to convert a mutable reference type to immutable. I know some people will disagree with me, but I think that is as it should be.



Yes, implementing const in Java seems like a hard thing to do, at least to me. As far as I know, Java objects know nothing about variables which refer to them. But then I'm ignorant of how const works in languages which do implement it, so maybe I'm addressing the wrong problem. So, suppose you create an object X and assign it to a const variable A. So now it's immutable. Next suppose you assign X to a non-const variable B. Presumably it's still immutable? And now suppose variable A goes out of scope and gets garbage-collected. Is X still immutable?
 
Stephan van Hulst
Bartender
Posts: 15737
368
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's been a while since I last used C++, so I don't recall the exact semantics of "const correctness", but I believe it works like this:

The const keyword doesn't actually make an object immutable. Instead, it modifies the formal type of a variable. It can be used in two different ways, when declaring a variable:

  • Make the variable itself unmodifiable. Similar to applying final to a variable in Java.
  • Allow only calls to read-only methods on the object held or referenced by the variable. The read-only methods of a class are indicated using the const keyword.

  • I believe you can assign from a variable of a normal pointer type to a variable of a "read-only" pointer type, but it's important to realize that the object pointed at is not immutable. You just can't call its mutators through the second variable.

    You wouldn't be able to assign from a "read-only" pointer type to a normal pointer type.

    I could be wrong about all of this; as I said, it's been a while.
     
    Campbell Ritchie
    Marshal
    Posts: 80111
    414
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Paul Clapham wrote:. . . So, suppose you create an object X and assign it to a const variable A. So now it's immutable. . . .

    Depending on where the keyword const appears, it can make the contents of the pointer it points t read‑only, as Stephan said, or make the pointer (not its contents) fixed. You can of course use const twice to get both features. I am not sure of the syntax.
     
    Tim Holloway
    Saloon Keeper
    Posts: 28410
    210
    Android Eclipse IDE Tomcat Server Redhat Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    This is a common construct in C:


    In this case, the pointer variable hello is defined to be constant and so is the "Hello, World!" string.

    That's right. In C, it has been common practice to allow string "constants" to be writable, and until const was introduced into C, there wasn't a darned thing you could do to prevent it. Indeed, this ability was not uncommonly exploited as a general programming practice.
     
    Stephan van Hulst
    Bartender
    Posts: 15737
    368
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    A small demo application in C++:
     
    Saloon Keeper
    Posts: 5583
    213
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Congratulations, Samy!

    Your topic got a mentioning in the October 2022 Journal, and so you earn a cow. Enjoy!
     
    Ranch Hand
    Posts: 607
    11
    Android Python Open BSD VI Editor Slackware
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Sami radwan wrote:I see. But that seems to be an advanced topic for a beginner. So as beginner all my objects should be declared final? For example, In Kotlin language I see most tutorials when they creating objects they use val not var which means that the reference is final even in introductory tutorials.



    In Kotlin we try indeed to make everything final.  Please notice I put from now on in bold all the words I deem interesting to seek on the internet to  deep dive to what i am introducing here.

    We try to use in fact a special paradigm that is a mix of functional programming and object oriented programming, the two paradigms are not "mutually exclusive" that means they can be both true, you can have structured programming that host both OOP (Object Oriented Programming) concepts as encapsulation, abstraction, inheritance, polymorphism with functional concepts as high order functions, lambda, tuples, currying functions, map/flatmap/filter

    In FP(Functional Programming) there is a concept called immutability that plays an important role and is quite essential to try to write less buggy apps, the reason is that pure functional programming(which Kotlin is not) tries to avoid the so called "side effects", a side effect modifies a mutable data structure, this is dangerous and considered evil, because you avoid complex "control structures" that do not help readability and are state error prone, you do not need to manage errors wrapping exceptions, and you have a safer multi-thread/concurrency experience.

    Kotlin is largely used with so called reactive concepts as Flow and RXKotlin(that is a wrapper of RXJava) so that you have a mutable object(that varies) and is usually isolated as private in a class and you assign this mutable object  to an immutable public one(that changes via an observer pattern) but offers to the "adapter" part of your architecture (see adapter pattern), an easier plug and play approach, unidirectional flow

    As you are following tutorials in Kotlin there is quite a chance you are interested in Android Architectures where all the modern so called stack (API) use in large misure the concept of reactive and immutability via ViewModels and Jetpack Compose
     
    get schwifty. tiny ad:
    Smokeless wood heat with a rocket mass heater
    https://woodheat.net
    reply
      Bookmark Topic Watch Topic
    • New Topic