So, I just started learning Java, and I discovered that there's no such thing as "pass by reference". I'm porting an application from C# to Java, and the original application has ints and doubles that are either "ref" or "out" parameters.
At first I thought I could pass in an "Integer" or a "Double", and since that was a Reference type, the value would be changed. But then I learned that those reference types are immutable.
So, then I made a "MutableInteger" class and a "MutableDouble" class, and I passed those into my functions. It works, but I guess I must be going against the original design intentions of the language.
Is "pass by reference" in general bad design? How should I change my way of thinking?
It seems reasonable to have a function like this:
bool MyClass::changeMyAandB(ref int a, ref int b) { // perform some computation on a and b here if (success) return true; else return false; }
Is that bad design?
2) For passing large sized arguments: If an argument is large, passing by reference (or pointer) is more efficient because only an address is really passed, not the entire object.
The reason is that Java object variables are simply references that point to real objects in the memory heap. Therefore, even though Java passes parameters to methods by value, if the variable points to an object reference, the real object will also be changed.
The difference between pass-by-reference and pass-by-value is that modifications made to arguments passed in by reference in the called function have effect in the calling function, whereas modifications made to arguments passed in by value in the called function can not affect the calling function.
Pass by value sends a copy of the data stored in the variable you specify, and pass by reference sends a direct link to the variable itself. So if you pass a variable by reference and then change the variable inside the block you passed it into, the original variable will be changed.
Object-oriented programming is done best if you structure your code into clean, understandable abstractions.
Numbers, as an abstraction, are immutable and have no identity (i.e. a "five" is always a "five" and there is no such thing as "multiple instances of five").
What you're trying to invent is a "mutable number" which is mutable and has identity. This concept is a bit unwieldy, and you'd probably be better off with modelling your problem with more meaningful abstractions (objects) than that.
Think in objects that represent something and have a specific interface, rather than in individual lumps of values.
It's not bad design in a language with proper support for it,(*) but when you have to define a MutableInt
class just to communicate between two methods, something is surely wrong.
The solution for the example you posted is to return an array of two ints and signal failure by either a null
return or an exception. This won't always work, so sometimes you have to...
Result
, that encapsulates the result of a computation (when you're dealing with an int
and a float
instead of two ints), and maybe has the actual computation as a method or constructor;(*) Just bad language design. In Python or Go, you'd return multiple values and stop worrying.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With