views:

93

answers:

4

I know this is a dumb question, but its really bugging me.

Take the following:

public <TParseable> LinkedList<TParseable> readAllParseable(
            Parseable<TParseable> parseable, boolean close) throws IOException
{
   LinkedList<TParseable> list = new LinkedList<TParseable>();
    byte[] delim = parseable.getDelimiterValue();
    boolean skipNL = parseable.skipNewLines();

    while(ready())
    {
     byte[] data = readTo(delim);
     parseable.parse(data);

     System.out.println(parseable);

     list.add((TParseable)parseable);
    }
    return list;
}

The println statement outputs the expected toString() value of parseable each time after the call to parseable.parse(data). However, the returned list has the correct number of elements, but they are all equal to the last value of parseable before the loop completed.

Is this because the list.add(xxx) parameter is passed by pointer rather than value?

A: 

You're putting in the same parseable object into the list each time. Each time parseable parses some data, it is being processed using the same parseable object.

digiarnie
+2  A: 

You only ever have a single instance of parseable in the code you posted. When you call add(parseable) you are adding a reference ("pointer" isn't really correct in Java) to parseable in your list.

By calling it repeatedly, without changing what object parseable refers to, you are simply adding more references to the same object to your list.

New objects are only ever created by the new keyword.

matt b
Thats what I thought, just wanted to check.
jdc0589
A: 

the object parseable is the same through the entire method. I assume that when you call parseable.parse(data) it changes the internal data in parseable. Since you keep putting the same object in the list, you are just operating on the same object every iteration.

tster
yea. It should be a static method that returns a new instance of an object, but unfortunately there is no way to do that with interfaces or abstract methods...which is really getting on my nerves lately.
jdc0589
If you find yourself wanting to use static methods on interfaces to create new objects, then what you need is the factory pattern.
tster
A: 

I think you conceptual problem is one of terminology. If I change "value" to "state", perhaps it will help clarify things ...

The println statement outputs the expected toString() state of parseable each time after the call to parseable.parse(data). However, the returned list has the correct number of elements, but they are all equal to the last state of parseable before the loop completed.

In reality, your program is using only one Parseable instance, and the method calls on that instance are changing its state.

Is this because the list.add(xxx) parameter is passed by pointer rather than value?

No. It is because the instance's state (as shown by toString()) is changing.

In fact, Java uses pass-by-value semantic for all parameters in method and constructor calls, irrespective of the type. The slightly confusing thing is that the "value" that is passed when you pass an Object / array in Java is a reference.

The three basic parameter passing mechanisms supported by programming languages are:

  • pass-by-value where you copy the value which might be a primitive value, a pointer / reference value, or (in some languages) a structured value. (In some languages, a value can be copied back on return, but that's just a logical extension of pass-by-value.)

  • pass-by-reference where you pass the address of a variable in the caller, allowing the callee to change that variable, and/or see the results of something else changing the variable.

  • pass-by-name which was a "clever" mechanism used in Algol-60 that turned out to be expensive to implement and too difficult for most programmers to use effectively.

I would stay away from using the terminology "pass by pointer". It is really just another way of saying "pass-by-value of a pointer" ... and if you try to think of it as something different, you only end up confused.

Stephen C