1

I'm working on translating some code from VisualBasic to Java and I've encountered a snag when using the ByRef keyword in VB. That doesn't exist in Java!

How should I simulate a ByRef call in Java?

Edit: Just to clarify for those who don't know VB, ByRef identifies a variable in the parenthesis after calling a function and makes it so that when that variable is changes inside of the function, it will also change higher up where it is called as opposed to ByVal where only the value of the variable is remembered. Changing a ByVal variable in the method will not affect the variable where it is called.

nick
  • 425
  • 2
  • 4
  • 10
  • 2
    In java everything is pass by value – Suresh Atta Aug 07 '13 at 13:53
  • 1
    You don't, since Java is only call by value. – Brian Roach Aug 07 '13 at 13:53
  • 5
    Well, you guys aren't wrong, but you're also not helping :p In some scenarios it can easily be simulated. And, it's worth mentioning that it's _pass-by-value-of-reference_ for objects. – keyser Aug 07 '13 at 13:54
  • 1
    It's also worth mentioning that "pass-by-value-of-reference" is the silliest, most redundant thing I've ever heard re: this topic. – Brian Roach Aug 07 '13 at 13:58
  • 2
    @BrianRoach how is accurately describing behavior "silly" or "redundant?" – resueman Aug 07 '13 at 14:01
  • I know I need to word this very carefully, you can pass a reference in Java just like a byRef in VB. Any Object in Java is a reference, which will work like you expect byRef in vb or -> (*.) in C++. Java programmers just seem to insist on calling the address a value which it technically is, and refuse to distinguish it as an address with it also is. Terminology and syntax are the only difference, practically you're doing the same thing. – Jason K. Mar 22 '17 at 19:16

2 Answers2

10

You can't. Everything in Java is passed by value, including object references. However you could create a "holder" object, and modify its value inside a method.

public class Holder<T> {
    T value;
    public Holder(T value) {
        this.value = value;
    }
    // getter/setter
}

public void method(Holder<Foo> foo) {
    foo.setValue(something);
}
keyser
  • 18,829
  • 16
  • 59
  • 101
Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • 4
    This is a fine answer, but questions like this (obvious duplicate of: [Is Java pass by reference](http://stackoverflow.com/questions/40480/is-java-pass-by-reference)) should be closed. Since you don't have the ability to vote-to-close yet, it should be flagged. – Steve P. Aug 07 '13 at 13:57
  • 1
    @SteveP. True. I'm a recent refugee from the Sun/Oracle forums, and there was very little one could do to handle the messages, so I'm still learning the ropes. – Kayaman Aug 07 '13 at 14:00
  • 2
    @SteveP. Is it a duplicate? While the crux of the question may be the same, that question seems to just have a bunch of lectures about how Java only allows one parameter-passing mechanism and does not seem to address the fact that the CLR `ref` concept is pretty easy to simulate in Java. Granted, those answers were very long and I didn't read them in depth, but a search on the page gave no hits for "holder", "proxy", and even "simulate" had only 1 that wasn't this answer. – Joel Aug 07 '13 at 14:05
  • @Joel There's a difference between duplicate questions and duplicate answers. The question is most definitely a duplicate. Regardless, at least one of the [answers](http://stackoverflow.com/a/707416/2073001) did touch on this. – Steve P. Aug 07 '13 at 15:06
  • 1
    @SteveP. Somewhere around 50-99% of all reputation on this site has been awarded on duplicate answers. I'm not saying it's how it supposed to be, but you're fighting an uphill battle :p And this one wasn't even one of them. – keyser Aug 07 '13 at 16:00
1

Java does not have an equivialent.

You either need to return the object from your method, and assign it back, e.g.

 myInteger = doSomething(myInteger);

Or you need to make a wrapper object, these are often name a Holder. If you have a variable named myInteger that you want some method to change, you pass it to that method as a member of the "Holder" class.

e.g. (This can naturally be made into a generic)

class IntegerHolder {
    public Integer myInteger;
 }

IntegerHolder myHolder;
myHolder.myInteger = myInteger;
doSomething(myHolder);
//use the possibly altered myHolder.myInteger now.

Inside doSomething, you can now change myHolder.myInteger , and the method calling doSomething() can see that change, e.g.

void doSomething(IntegerHolder holder)
{
    holder.myInteger = holder.myInteger * 100;
}
nos
  • 223,662
  • 58
  • 417
  • 506