1

Hello Guys :D Why can't I execute the following code withoud getting a runtime exception? How should it be rewritten? I am migrating from C++ where I could easily do that I suppose :D.

class MyJavaClass {
    public static void main(String args[]) {
        Dog bushui_RIP = new Dog();
        Dog fellow = null;
        bushui_RIP.bark(fellow);
        fellow.bark();
    }
}
class Dog {
    public void bark(Dog buddy) {
        buddy = this;
    }
    public void bark() {
        System.out.println("I am barking!!!");
    }
}
OneMoreVladimir
  • 1,653
  • 3
  • 21
  • 32
  • possible duplicate of [Is Java pass by reference?](http://stackoverflow.com/questions/40480/is-java-pass-by-reference) – McDowell May 30 '11 at 13:46

7 Answers7

5

fellow is null, therefore there is no object that can bark.

Miki
  • 7,052
  • 2
  • 29
  • 39
  • But I assume it's assigned bushui_RIP object's reference... How should it look like? – OneMoreVladimir May 30 '11 at 13:44
  • As McDowell said, it is a reference variable passed by value to the method. You can do that in C, but not in Java. – Miki May 30 '11 at 13:46
  • Sorrow, can you help me to correct the code? How references are passed by reference?:D – OneMoreVladimir May 30 '11 at 13:47
  • @OneMoreVladimir Java is always pass by value. – Robin May 30 '11 at 13:47
  • 4
    Um... To correct the code I believe I would need to know what are you trying to achieve; currently what I understand you want simply `Dog fellow = bushui;`. Optionally, modify the `bark` method to contain `return this;` (without the assignment and the parameter), then make it `Dog fellow = bushui.bark();`. Be aware, though, that this will NOT create a new dog, both `fellow` and `bushui` will be exactly the same object. To create a new dog, simply call `new Dog();`. – Miki May 30 '11 at 13:51
  • You can pass references by reference by encapsulating them in a class. See my answer. – Eser Aygün May 30 '11 at 14:11
5

Dog fellow is a reference variable, but it is passed by value to the method.

McDowell
  • 107,573
  • 31
  • 204
  • 267
2

Dog fellow = null;

you gotta Initialise it before you can make your dogs bark.

RMT
  • 7,040
  • 4
  • 25
  • 37
2

Change Dog fellow = null; to Dog fellow = new Dog();.

melhosseiny
  • 9,992
  • 6
  • 31
  • 48
2

The problem is your local variable fellow. It is null when you try to call bark() of it.

When you call bushui_RIP.bark(fellow) it is indeed a pass by reference, but the reference itself is passed as value (how else). So you assign to a local variable buddy in your bark(Dog) function without touching the original reference fellow.

What is bark(Dog) supposed to do? Clone this and return a new instance of Dog or assign this as it is to a reference?

Hyperboreus
  • 31,997
  • 9
  • 47
  • 87
  • Is there a way to pass a reference by reference?:D – OneMoreVladimir May 30 '11 at 13:50
  • You could do something like this, but I don't see the sense behind it: public class Main { public static void main(String args[]) { Dog bushui_RIP = new Dog(); DogReference fellow = new DogReference (null); bushui_RIP.bark (fellow); fellow.ref.bark(); } } class DogReference { public Dog ref = null; public DogReference (Dog d) {this.ref = d;} } class Dog { public void bark (DogReference other) { other.ref = this; } public void bark() { System.out.println("I am barking!!!"); } } – Hyperboreus May 30 '11 at 13:53
  • @OneMoreVladimir No. Things work differently in Java - no pointers! – Adrian Mouat May 30 '11 at 13:53
  • @OneMoreVladimit. Perhaps if you post the C++ code you must migrate, we could take a look at it and see how to "javaficate" it. – Hyperboreus May 30 '11 at 13:58
2

In Java, you cannot pass object references by reference, as you do in C++ by writing Dog **ppDog. You can pass the value (this) to the caller as a return value or in a field.

Or, you can use "the cell pattern" as I call it. Firstly, define your Cell<T> class that holds a reference to an object with type T:

class Cell<T> {
    public T item;

    Cell(T item) {
        this.item = item;
    }
}

Then, you can write:

private void bark(Cell<Dog> buddy) {
    buddy.item = this;
}

...

Dog bushui_RIP = new Dog();
Cell<Dog> fellow = Cell(null);
bushui_RIP.bark(fellow);
fellow.item.bark();
Eser Aygün
  • 7,794
  • 1
  • 20
  • 30
  • What purpose does this solve instead of simply returning the value you wish to have assigned? This seems to make the coding more complex instead of simpler. – Robin May 30 '11 at 14:36
  • In this case, I agree. You should just return the value. However, there are cases that I needed to use "the cell pattern". For example, imagine that the value change has to be initiated by a foreign object. In that case, you cannot just call a function and store the result; you have to find a way to pass a reference to the reference. – Eser Aygün May 30 '11 at 14:52
1

Another soltuion is to change bark() to be static.

public static void bark() {
    System.out.println("I am barking!!!");
}

((Dog) null).bark();
// is the same as
Dog.bark();

I am migrating from C++ where I could easily do that I suppose

I didn't think you would easily de-reference a NULL pointer without gettting a segmentation fault which kills your application.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130