C++ vs Java -- const vs final

Started by
18 comments, last by Antheus 15 years, 4 months ago
Hello all.. I'm still learning Java at university, although I know C++ fairly well. I've got a question about final in Java in comparisson to const in C++. Some uses of const in C++:
class Foo
{
    const int Bar( const double Naz ) const;
}

-----
const int Bar( const double Naz ) const;
^^^^^^^^^
Returns a constant int
-----
const int Bar( const double Naz ) const;
               ^^^^^^^^^^^^
Requires a constant double
-----
const int Bar( const double Naz ) const;
                                  ^^^^^
Foo::Bar() may not change the instance of Foo that it's called from
Also, Foo::Bar() may be called on constant instances of Foo
-----
In Java, I know how to use the first two with final. Is there something like the last example I gave in Java aswell? Thanks for your time
Advertisement
The standard Java way of doing this is to return an immutable interface. Something like:

interface ImmutablePoint{  int getX();  int getY();}class Point implements ImmutablePoint{  int x, y;  int getX() { return x; }  int getY() { return y; }}boolean isUnderPoint(ImmutablePoint point) // 'point' cannot be chanced by this method{  // ..}
Quote:Original post by c4c0d3m0n
const int Bar( const double Naz ) const;
^^^^^^^^^
Returns a constant int

Which doesn't make much sense.

Quote:Original post by c4c0d3m0n
const int Bar( const double Naz ) const;
^^^^^^^^^^^^
Requires a constant double

No, it doesn't. You can pass a non const double just fine because the value is copied anyway.

Note that in Java final UserType object; is somewhat like UserType * const object in C++, which means that you cannot make object point to a different Object, but you can mutate the Object that it points to.
*grumble* This is why Java confuses me so much, pointers, references, instances, it's all one big pile of steaming foobar. I guess I'll be going back to C++ very fast after the course is over.


@DevFred
I realise it doesn't make much sense, it was more of an example to show what I meant about the different positions of const. I guess chaning all those into constant references would make more sense :)

@OrangyTang
Does this mean that I need to create two classes of everything I want to use constant references of (and effectively two *.java files)? I must say I don't really understand what the Java developers were thinking when they designed this feature... Maybe there is a good reason I'm missing.



As I understand now, when I write boolean isUnderPoint(Point p), p is automatically passed by reference (since there is no NULL pointer if I'm not mistaken). If I'd go and write boolean isUnderPoint(final Point p), it would mean that p can't point to another object, but that the current object can be changed through p (which would make p a pointer! confusing..)


Thanks for clarifying a few things, but I'm afraid I'm still a little in the dark about the Java way of things. The book that the course is built upon is not very good either (even the professor keeps complaining about it oddly enough). Is there maybe some sort of book that teaches Java to people that know C++? I can imagine I'm not the first person in this situation. I'd like to learn Java properly, as I believe a good programmer should know more than one language.
Quote:Original post by c4c0d3m0n
*grumble* This is why Java confuses me so much, pointers, references, instances, it's all one big pile of steaming foobar.

Actually, it is very simple in Java. Java references are a lot like C++ pointers, C++ references do not exist in Java, Classes define reference types, and everything is passed by value.

Quote:Original post by c4c0d3m0n
when I write boolean isUnderPoint(Point p), p is automatically passed by reference (since there is no NULL pointer if I'm not mistaken).

NO! There is no pass by reference in Java, everything is passed by value. In this case, the reference p is passed by value. p is NOT a Point, it is a reference to a point. Java does not allow storing objects directly in variables (that would be value semantics), only references to objects (this is called reference semantics).

And sure there's a null pointer:
Point p = null;p.doSomething(); // NullPointerException

Quote:
James Gosling, et al., The Java Programming Language, 4th Edition
Some people will say incorrectly that objects are passed "by reference." In programming language design, the term pass by reference properly means that when an argument is passed to a function, the invoked function gets a reference to the original value, not a copy of its value. If the function modifies its parameter, the value in the calling code will be changed because the argument and parameter use the same slot in memory.... The Java programming language does not pass objects by reference; it passes object references by value. Because two copies of the same reference refer to the same actual object, changes made through one reference variable are visible through the other. There is exactly one parameter passing mode -- pass by value -- and that helps keep things simple.
Wow! Thanks! This really cleared up a few things!


One thing left... The quote states that having just one parameter passing mode keeps things simple... But what if I want to pass a copy of my object to a function? How would I do that? I've had situations in C++ where I had to pass a copy.

Also, why do certain built-in functions of Java give back a copy of a value instead of a reference to it? I'd actually expect Math.max( i, j ) to return i or j instead of the actual value stored inside the variable..
Quote:Original post by c4c0d3m0n
But what if I want to pass a copy of my object to a function? How would I do that? I've had situations in C++ where I had to pass a copy.

Well, instead of passing a reference to the original by value, you pass a reference to a clone (which you have to provide) by value.
foo.someMethod(myObject.clone());

In order for this to work, MyClass has to
- implement the interface java.lang.Cloneable
- override the clone() method
-- first call super.clone() to get a shallow (bit by bit) copy
-- then clone all fields for which a shallow copy isn't good enough

Example:
public class CloneExample implements Cloneable{    private int i;    private boolean b;    private int[] a;    private String s;        public CloneExample clone()    {        CloneExample that = null;        try        {            // make a bit by bit copy by calling the inherited clone() method            that = (CloneExample) super.clone();            // a references the original array, so we have to manually clone it            that.a = this.a.clone();            // We don't have to clone s because Strings are immutable.            // this.a and that.a both refer to the same object, but that is no problem.        }        catch (CloneNotSupportedException e)        {            System.err.println("this shouldn't happen");            e.printStackTrace();        }        return that;    }}

In Java, copying Objects is hard, while sharing Objects is easy. It is the opposite in C++. It's a thing you have to get used to when coming from C++ to Java. You very rarely have the need to copy objects.

Quote:Original post by c4c0d3m0n
Also, why do certain built-in functions of Java give back a copy of a value instead of a reference to it?

Because in Java, there is no such thing as a reference to a primitive.

Quote:Original post by c4c0d3m0n
I'd actually expect Math.max( i, j ) to return i or j instead of the actual value stored inside the variable.

What would you expect Math.max(a*b, c*d) to return then?

References in the C++ sense DO NOT EXIST in Java. (That's why the common swap function is impossible in Java.) Java has crippled pointers called references, but they have nothing to do with the references from C++. You cannot have indirections to variables in Java, only indirections to anonymous Objects.

Once again, variables NEVER store Objects directly in Java. A variable either stores a primitive, or a reference to an Object. If you pass an int, it gets passed by value. If you pass a reference, it gets passed by value. YOU CANNOT PASS OBJECTS (neither by value nor by reference), only references to objects (by value, as always).

- Cup Size -- a story about variables
- Pass-by-Value Please (Cup Size continued)
- Java is Pass-by-Value, Dammit!
Thanks for all the info! I hope I can appreciate Java a bit more now that these unclarities have been cleared. However, I think my language of preference will stay C++ for a while, maybe untill I try my heart at another language...
Quote:Original post by c4c0d3m0n
I think my language of preference will stay C++ for a while, maybe untill I try my heart at another language...

1. As long as you THINK in language X, it is very hard to appreciate language Y.

2. If you already know REAL C++ (if you know what RAII and template template parameters mean, you probably do), Java may just appear like a crippled C++ to you. The interesting parts of Java are not language features, but what you can easily do with the language (multithreading, networking, portable GUIs).

3. If you want to become a better programmer, it is very important to learn new languages. If Java doesn't wow you (and it probably doesn't), I recommend Haskell (or any other functional programming language) for a completely different view on programming.
final class cannot be subclassed.
final method cannot be overriden.
final variable can be only assigned once.

That's it. Period. As such, it's not really related to C++ const.

Java implements const semantics through immutable types, where their interface does not allow internal values to be changed (it has get(), but not set()). Final does not provide that.

Also, anything that is not a primitive type in Java is C++ equivalent of shared_ptr<T> in an application that doesn't use references or pointers in any way and passes everything by value.

Arrays are shared_ptr<vector<T>>.

Generics in Java are dynamic_cast<T>, not like templates in C++.

It really is that simple.

I'm wondering if find/replace could be used to port Java code to C++ in this way...

This topic is closed to new replies.

Advertisement