Does Java Have Something Like C#'s Ref and Out Keywords

Does Java have something like C#'s ref and out keywords?

No, Java doesn't have something like C#'s ref and out keywords for passing by reference.

You can only pass by value in Java. Even references are passed by value. See Jon Skeet's page about parameter passing in Java for more details.

To do something similar to ref or out you would have to wrap your parameters inside another object and pass that object reference in as a parameter.

What's the difference between the 'ref' and 'out' keywords?

ref tells the compiler that the object is initialized before entering the function, while out tells the compiler that the object will be initialized inside the function.

So while ref is two-ways, out is out-only.

The performance cost to using ref instead of returning same types?

The main time that "ref" is used in the same sentence as performance is when discussing some very atypical cases, for example in XNA scenarios where the game "objects" are quite commonly represented by structs rather than classes to avoid problems with GC (which has a disproportionate impact on XNA). This becomes useful to:

  • prevent copying an oversized struct multiple times on the stack
  • prevent data loss due to mutating a struct copy (XNA structs are commonly mutable, against normal practice)
  • allow passing a struct in an an array directly, rather than ever copying it out and back in

In all other cases, "ref" is more commonly associated with an additional side-effect, not easily expressed in the return value (for example see Monitor.TryEnter).

If you don't have a scenario like the XNA/struct one, and there is no awkward side effect, then just use the return value. In addition to being more typical (which in itself has value), it could well involve passing less data (and int is smaller than a ref on x64 for example), and could require less dereferencing.

Finally, the return approach is more versatile; you don't always want to update the source. Contrast:

// want to accumulate, no ref
x = Add(x, 5);

// want to accumulate, ref
Add(ref x, 5);

// no accumulate, no ref
y = Add(x, 5);

// no accumulate, ref
y = x;
Add(ref y, x);

I think the last is the least clear (with the other "ref" one close behind it) and ref usage is even less clear in languages where it is not explicit (VB for example).

Why are objects automatically passed by reference?

Why are objects automatically passed by reference?

They're not.

Is there any particular benefit from forcing the cloning process for them instead of treating objects more like int, double, boolean, etc. in these cases?

There's no "cloning process" for reference types, only for value types.

I think you're confusing different concepts:

  • value types vs. reference types

    For value types (such as primitive numeric types, enums, and structures like DateTime), the value of the variable is the object itself. Assigning the variable to another (or passing it as a parameter by value) creates a copy of the object.

    For reference types (such as object, string, classes (not structs) etc), the value of the variable is a reference to the object. Assigning the variable to another (or passing it as a parameter by value) creates a copy of the reference, so it still refers to the same object instance.

  • passing parameters by value vs. by reference

    Passing parameters by value means that you pass a copy of the value. Depending on whether it's a value type or reference types, that means a copy of the object itself, or a copy of the reference. If the callee modifies members of a value type passed as a parameter, the caller won't see the changes, since the callee is working on a copy. On the other hand, if the callee modifies members of a reference type passed as a parameter, the caller will see the changes, because the callee and caller both have a reference to the same object instance.

    Passing parameters by reference means that you pass a reference to a variable (which may be a variable of value type or reference type). The value is not copied: it is shared between the caller and the callee. So any change made by the callee (including assignment of a new value to the parameter) will be seen by the caller.

    Unless specified otherwise (with the ref or out keywords), all parameters are passed by value, including reference types. It's just that for reference types, the value that is passed is a reference, but it's still passed by value.

I suggest you read Jon Skeet's article Parameter passing in C# for a better explanation.

Passing objects by reference or not in C#

Since SomeClass is a class, then it is automatically passed by reference to the AddToList method (or more accurately, its reference is passed by value) so the object is not copied. You only need to use the ref keyword if you want to re-assign the object the reference points to in the AddToList method e.g. Item = new SomeClass();.

Why are 'out' parameters in .NET a bad idea?

Well, they aren't a bad idea I think. Dictionary<K, V> has a TryGetValue method which is a very good example why out parameters are sometimes a very nice thing to have.

You should not overuse this feature of course, but it's not a bad idea per definition. Especially not in C# where you have to write down the out keyword in function declaration and call which makes it obvious what's going on.

Impact of using the 'ref' keyword for string parameters in methods in C#?

When I use this method, the compiler creates a copy of the text for the method, right?

No, it doesn't. string is a reference type, and the compiler will create a new stack variable which points to the same string represented at a given memory address. It won't copy the string.

When you use ref on a reference type, there won't be a copy of the pointer to the string created. It will simply pass the already created reference. This is useful only when you want to create an entirely new string:

void Main()
{
string s = "hello";
M(s);
Console.WriteLine(s);
M(ref s);
Console.WriteLine(s);
}

public void M(string s)
{
s = "this won't change the original string";
}

public void M(ref string s)
{
s = "this will change the original string";
}

So is it good for performance using ref like this?

The performance gains won't be noticeable. What will happen is other developers getting confused as to why you used ref to pass the string.



Related Topics



Leave a reply



Submit