0

I have a very basic doubt in Java.

Here is a code I have written. From a method in class A in package A, I try to instantiate an object of class b of a different package and call its method, to which I pass a list.

 parseObjectList = new ArrayList<ParseObject>();
 pullAllService.pullAllData(queryType,parseObjectList);

and in the function I do some manipulation:

 public void pullAllData(String queryType,List<ParseObject> parseObjectList)
{
    ParseQuery<ParseObject> query = null;

    List<ParseObject> parseObjects = parseObjectList;

    if(queryType.equals("a"))
    {
        query = new ParseQuery<ParseObject>("a");
    }
    else if(queryType.equals("b"))
    {
        query = new ParseQuery<ParseObject>("b");
    }



    try {
        parseObjects = query.find(); //I get the list

       /* final List<ParseObject> finalParseObjectList = parseObjectList;
        curActivity.runOnUiThread(new Runnable() {
            public void run() {
                ToastMessageHelper.displayLongToast(curActivity, "Objects found : ");
                for (int i = 0; i < finalParseObjectList.size(); i++) {
                    ToastMessageHelper.displayLongToast(curActivity, finalParseObjectList.get(i).get("Name").toString());
                    System.out.println();
                }
            }
        });
    */

    } catch (ParseException e) {
    e.printStackTrace();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }


}

after which if I try to print the list in class A's method. I get an empty list.

But if I do this,

 parseObjectList = new ArrayList<ParseObject>();
 parseObjectList = pullAllService.pullAllData(queryType,parseObjectList);

and make it return the list from pullAllData() (by changing the return type and returning the list) , I get the list with the expected data.

I thought that just by passing the parseObjectList into the function, the passed parameter would behave as a reference and automatically be assigned the intended data. What's wrong here?

SoulRayder
  • 5,072
  • 6
  • 47
  • 93
  • 2
    You seem to be expecting this: `parseObjects = query.find()` to affect `parseObjectList`. It doesn't. Even if Java used pass-by-reference, it wouldn't. – Jon Skeet Mar 02 '15 at 09:57
  • Actually this code is part of an android app, hence that part. I am calling this function from a non-UI thread and hence the code. But that part is'nt a part of my doubt here – SoulRayder Mar 02 '15 at 09:59
  • 1
    This is because you are not changing the data in `parseObjectList`. You just pointed `parseObjects` to the `parseObjectList`. But after that you pointed `parseObjects` to another list `query.find()`, which means you are no more referring to parseObjectList. – shikjohari Mar 02 '15 at 10:02

1 Answers1

3

Java is a pass by value language. Passing a List reference to a method allows the method to mutate the List referenced by the reference, but it can't change the value of the List reference that was passed to it.

You can do something like this to add the elements to the list that was passed to your method :

parseObjectList.addAll(query.find());
Eran
  • 387,369
  • 54
  • 702
  • 768
  • So I have to resort to me second method to achieve the expected result then? – SoulRayder Mar 02 '15 at 09:58
  • 1
    No you just made an error - look at @Jon Skeets comment – Elemental Mar 02 '15 at 09:59
  • 1
    @SoulRayder No, just replace `parseObjects = query.find();` with `parseObjectList.addAll(query.find());` – Eran Mar 02 '15 at 09:59
  • Thanks a lot :) What exactly is the difference between this solution and what I did? – SoulRayder Mar 02 '15 at 10:01
  • I got it :) Java passes references *by value*. So even if the address of the list is passed, I was previously changing the value stored in the refernce and it was not reflecting outside the method call. Thanks a ton @Eran – SoulRayder Mar 02 '15 at 10:06