2

I know that 'final' keyword specified in method definition declare that these method cannot be overridden. But what if I want a method to return a final object? How do you specify this in Java?

class A{
    final int x;
    A(){
        x = 5;
    }
    final int getx(){
        return x;
    }
}
class B extends A{
    final int x;
    B(){
        x = 5;
    }
    final int getx(){
        return x;
    }
}
class he{
    public static void main(String args[]){
        A a = new A();
        final int x = a.getx();
        System.out.println(x);
    }
}

The above code gives a compilation error. I know the reason that I am overriding a final method. But my intention was to return a final object from getx() (i.e return x as a final integer).

This is my C++ equivalent code. It works just fine.

#include <bits/stdc++.h>
class A{
public:
    const int x;
    A():x(5){
    }
    const int getx(){
        return x;
    }
};
class B:public A{
public:
    const int x;
    B():x(5){
    }
    const int getx(){
        return x;
    }
};
int main(){
    A *a = new A();
    const int x = a->getx();
    std::cout<<x<<std::endl;
    return 0;
}

This is because C++ has a two different keywords - "const" and "final". In C++ 'final' keyword is specified in the end of function prototype, something like this:

virtual int getx() final {}

And so the two keyword distinguishes "what is the return type of a method" and "which methods cannot be overridden".

My question is: Is there a way of doing the same in Java?

Sushant
  • 122
  • 11

1 Answers1

4

final in Java and const in C++ are very different things and trying to applying ideas from C++ about constants to Java does not work.

In Java, final for datatypes means

  1. This object is immutable (only for native types).
  2. The reference to this object is immutable (for user defined types). This means that the variable holding the reference to this object cannot be changed to point to a different object. It doesn't mean however that the underlying object is immutable.

Now, if I am returning a value from a function in Java, it is either a native type, which we return by value, or a user defined type, which we return by reference. In both of these cases, the final qualifier on our return value is redundant.

  1. Rvalues returned from functions for native types are already immutable.
  2. References returned from functions are also rvalues and are also immutable.

In C++ however, a const qualified return value (let's say a reference to const for simplicity) means that the object underlying the returned reference is immutable, and so you cannot call non const functions using that reference.

final was added in C++11 and means that this member function cannot be overridden by an inheriting class (same as Java).

The takeaway is that Java does not have const correctness that same way that C++ does and your life will be easier if you don't mix these concepts.

serv-inc
  • 35,772
  • 9
  • 166
  • 188
John Dengis
  • 192
  • 1
  • 8
  • 1
    This answer is incorrect. The distinction between "native" types and "user-defined" types isn't a thing in Java, whatever it's supposed to mean. The word "immutable" is used in a meaningless way. "References returned from functions are also rvalues and are also immutable." Huh? References aren't called "immutable" in Java, they're called `final` if unchangeable. Java doesn't even have a mechanism to put a "final qualifier on our return value", let alone a "redundant" way. I can't find much if anything meaningful in this answer. – Lew Bloch Jun 05 '17 at 07:18
  • Regarding a "user defined type, which we return by reference" - that's not true either. It's got nothing to do with "user-defined" types, and it doesn't return objects "by reference", it returns reference (i.e., pointer) values, or one could say it returns references (i.e., pointers). – Lew Bloch Jun 05 '17 at 07:25
  • There is in fact a distinction between native types and user defined types in Java. Native types are things like int, long, float, double, and char. These types are passed by value into functions, and when returned from a function, the value is returned (not a reference). On the other hand, user defined types (which might not have been the best word to use) are passed by reference into functions and when used as a return value, a reference is returned (this is why one needs to use container objects like Double and Integer in Java if they want to pass a native object by reference). – John Dengis Jun 05 '17 at 07:42
  • I think your pedantry is getting in the way of you seeing what I'm really saying here. – John Dengis Jun 05 '17 at 07:45
  • I was saying that Java doesn't have final return qualifiers because they are redundant. It doesn't mean anything to return a final reference from a function because a final qualifier means the reference can't point to any other object, but return values from functions are rvalues, and rvalues can not be changed. – John Dengis Jun 05 '17 at 07:52
  • Nothing is passed by reference to methods in Java. All arguments are passed by value. – Lew Bloch Jun 06 '17 at 06:48