0

I'm a Java programmer transitioning to C++ and need some clarification on how Java is considered "pass-by-value", rather than a "hybrid". Java's baz() behaves identically to the C++'s foo() below, which is a pass-by-reference trait.

Edit: What I'm trying to understand is why bar() and baz() are pass-by-value despite different behavior. I can't find this specific answer on the forums.

Java

public class CountKeeper {

  private static void baz(CountKeeper ck) {
    ck.inc();
  }

  public static void main(String[] args) {
    CountKeeper ck = new CountKeeper();
    System.out.println(ck.count()); // 0
    baz(ck);
    System.out.println(ck.count()); // 1
  }

  private int count;

  private int count() {
    return count;
  }

  private void inc() {
    count++;
  }
}

C++

#include <iostream>

class CountKeeper
{
public:
  CountKeeper();
  CountKeeper& operator++();
  int count();
private:
  int count_;
};

CountKeeper::CountKeeper() :
  count_(0)
{}

CountKeeper& CountKeeper::operator++()
{
  ++count_;
  return *this;
}

int CountKeeper::count()
{
  return count_;
}

//pass by reference
void foo(CountKeeper& ck)
{
  ++ck;
}

//pass by value
void bar(CountKeeper ck)
{
  ++ck;
}

int main()
{
  CountKeeper ck;
  std::cout<<ck.count(); // 0
  foo(ck);
  std::cout<<ck.count(); // 1
  bar(ck);
  std::cout<<ck.count(); // 1
  return 0;
}
Agrim Pathak
  • 3,047
  • 4
  • 27
  • 43

3 Answers3

2

No. Java is always pass by value. But what appears to be an Object is actually an Object reference, so that (the value of the reference) is the value that is passed when you pass an Object.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
2

Passing a CountKeeper object to baz passes a copy of a reference to that object. Therefore, baz can change the state of that object (since the reference points to the same object), but it can't change the reference itself.

If instead of

  private static void baz(CountKeeper ck) {
    ck.inc();
  }

You'd write

  private static void baz(CountKeeper ck) {
    ck = new CountKeeper();
  }

the caller of the method won't see any change in the object referenced by the ck variable that was passed to baz.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • What I'm trying to understand is **why we get different behavior and why these methods are called pass-by-value/reference despite different behavior**. I think I understand the different behavior part. Tell me if this sounds correct: A) foo() takes an actual reference B) bar() takes a copy of an object C) baz() takes a copy of a reference. Is this correct? If so, why are bar() and baz() called pass-by-value? – Agrim Pathak Oct 26 '14 at 07:59
  • @AgrimPathak I can't talk with certainty about the c++ code, since it's been years since I worked with c++. In Java, there are primitive types and reference types. Both are passed by value to methods. Since reference values that were passed to methods point to the original objects, they can still be used to mutate the objects referred by them. On the other hand, in c++, when you pass an object by value (as in `bar`) the object itself is copied, so any changes to it done in the method are local to the method. – Eran Oct 26 '14 at 08:14
  • @AgrimPathak: A C++ equivalent to your Java code would be: `void baz(CountKeeper *ck) { ck->inc(); } int main() { CountKeeper *ck = new CountKeeper; }` The type `CountKeeper` in Java is a pointer-to-object type. The syntax of types is different between C++ and Java, but you shouldn't let that confuse you. In Java you are dynamically allocating a new instance using `new CountKeeper()`, which returns an object pointer, like `new CountKeeper` in C++. You were not doing that in your C++ code, so you are comparing apples and oranges. – newacct Oct 28 '14 at 02:41
  • @AgrimPathak: You have a variable of object type in your C++ code, where there is no such thing in Java (there are no "object types" in Java). There are also no equivalent to C++ references (`&`) in Java. – newacct Oct 28 '14 at 02:41
1

Everything in Java is pass by value. I think it would be fun and beneficial to read this Parameter passing in Java - by reference or by value?.

kolonel
  • 1,412
  • 2
  • 16
  • 33