Reply to topic  [ 8 posts ] 
References in Java? 
Author Message
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 6:36 pm
Posts: 5150
Location: /dev/tty0
Reply with quote
In Java, you might have a class where you define a private array (for instance). Every method in the class can access this array and modify the contents.

If you pass the array to a method in a different class (or a different instance of the same class), you are copying the whole array and giving that method a complete clone. This means that if that method in the other class changes the contents of the array, it has to either pass back the changes or the whole array (copying it again).
If you try to encapsulate the array in another class and pass the instance of the array class across, you still have to pass it back to get the changes.

Although I'm not sure when you would want to do this, it makes me wonder if you can pass references instead? It would be a lot more lightweight (unless the JVM does only reference the original array to begin with and then only creates values when they are changed, similar to deduplication).


Thu Feb 10, 2011 4:48 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 7:35 pm
Posts: 6580
Location: Getting there
Reply with quote
OK, I knew there was something I had heard/read about this in the past.

Java does not pass objects by value. When you pass an object (Array, String, Integer (not int), etc...) it passes the value of the pointer into the new class.

If you create an instance of an object and call it myObject then what you have done is create an object in the memory stack and then define a pointer to that memory stack position. The pointer is called myObject.

myObject is not the actual object only a pointer to where it sits.

A quick test can verify this...

Code:
public class Person
{
    private String myName;

    public Person(String name)
    {
        myName = new String(name);
    }

    public void setName(String name)
    {
        myName = new String(name);
    }

    public String getName()
    {
        return myName;
    }
}


Code:
public class Changer
{
    private Person myPerson;

    public Changer(Person p)
    {
        myPerson = p;
        changeName();
    }

    public void changeName()
    {
        myPerson.setName("Oliver");
    }
}


Code:
public class Main
{
    public static void main(String[] args)
    {
        Person p = new Person("Daniel");
        Changer c = new Changer(p);
        System.out.println(p.getName());
    }

}


OK, so this is a very simple program that defines a person p. Then passes person p into Changer who then saves the input person as its own object. It then changes the name of its own person.

Then the main program displays the name of its person p.

If Java had passed the value of p into Changer and then it had copied it the program would print out Daniel. however, it prints out Oliver.

This is because there is only one person in the program but "p" and "myPerson" are two separate pointers to the same Person Object.

I hope that makes sense?

This is a good explanation of it also...

http://javadude.com/articles/passbyvalue.htm

::EDIT:: The only reason I used "myName = new String(name);" rather than "myName = name" is so that I could ensure I wasn't saving values of strings and getting them passed back etc... This prob wasn't necessary but what the hey :D

_________________
Oliver Foggin - iPhone Dev

JJW009 wrote:
The count will go up until they stop counting. That's the way counting works.


Doodle Sub!
Game Of Life

Image Image


Thu Feb 10, 2011 10:07 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 6:36 pm
Posts: 5150
Location: /dev/tty0
Reply with quote
Hmmm, see that's not what I get in this sample code:
Code:
class MyTest {
   
   MyArray ma = new MyArray();
   
   public MyTest(){
      run();
      printArray();
      NewTest nt = new NewTest(ma);
      printArray();
   }
   
   private void run(){
      for(int i = 0; i < ma.getLength(); i++){
         ma.writeIndex(i, i);
      }
   }
   
   private void printArray(){
      for(int i = 0; i < ma.getLength(); i++){
         System.out.println(ma.readIndex(i));
      }
   }
   
   public static void main(String[] args){
      MyTest mt = new MyTest();
   }
   
}

class NewTest{
   
   public NewTest(MyArray ma){
      for(int i = 9; i > 0; i--){
         ma.writeToIndex(i, i);
      }
   }
   
}

class MyArray{
   
   private int[] array = new int[10];
   
   public int readIndex(int index){
      return array[index];
   }
   
   public void writeToIndex(int index, int value){
      array[index] = value;
   }
   
   public int getLength(){
      return array.length;
   }
   
}


I would expect the second printArray() to print backwards...


Fri Feb 11, 2011 4:53 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 7:35 pm
Posts: 6580
Location: Getting there
Reply with quote
I haven't had a proper look but I have a feeling you are instantiating a new version of the array somewhere.

I wrote my own test to keep it as simple as possible...
Code:
public class Changer
{
    public Changer(int[] a)
    {
        for (int i=0 ; i<9 ; i++)
        {
            a[i] = 8-i;
        }
    }
}

and...
Code:
public class Main
{
    public Main()
    {
        int myArray[] = new int[9];

        for(int i = 0 ; i<9 ; i++)
        {
            myArray[i] = i;
        }

        printArray(myArray);

        Changer c = new Changer(myArray);

        printArray(myArray);
    }

    public void printArray(int[] a)
    {
        System.out.print("{ ");

        for(int i=0 ; i<9 ; i++)
        {
            System.out.print(a[i]);

            if(i < 8)
            {
                System.out.print(" , ");
            }
        }

        System.out.println(" }");
    }

    public static void main(String[] args)
    {
        new Main();
    }
}


This outputs the following...

{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 }
{ 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 }

Which means that the Changer object has written to the same Array as myArray in the Main object.

I'll see if I can spot anything in your example.

_________________
Oliver Foggin - iPhone Dev

JJW009 wrote:
The count will go up until they stop counting. That's the way counting works.


Doodle Sub!
Game Of Life

Image Image


Fri Feb 11, 2011 7:10 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 7:35 pm
Posts: 6580
Location: Getting there
Reply with quote
Ah, I spotted it...

You have done the same thing that almost caught me out :D

In NewTest...

Code:
public NewTest(MyArray ma)
{
    for(int i = 9; i > 0; i--)
    {
        ma.writeToIndex(i, i);
    }
}


The loop in here does the same as the loop in the run method...

Code:
private void run()
{
    for(int i = 0; i < ma.getLength(); i++)
    {
        ma.writeToIndex(i, i);
    }
}


They both set the array to {1,2,3,4,5,6,7,8,9} (almost) it's just that one starts from 1 (at the beginning) and the other starts from 9 (at the end).

Change the NewTest codes to this...

Code:
public NewTest(MyArray ma)
{
    for(int i = 9; i >= 0; i--)
    {
        ma.writeToIndex(i, 9-i);
    }
}

_________________
Oliver Foggin - iPhone Dev

JJW009 wrote:
The count will go up until they stop counting. That's the way counting works.


Doodle Sub!
Game Of Life

Image Image


Fri Feb 11, 2011 7:16 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 6:36 pm
Posts: 5150
Location: /dev/tty0
Reply with quote
Ah ha, I do feel the idiot!

:P


Fri Feb 11, 2011 11:32 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 7:35 pm
Posts: 6580
Location: Getting there
Reply with quote
No problemo.

I miss stuff like this everyday. It seems it's only ever when other people are looking that I can see any errors in my own code.

_________________
Oliver Foggin - iPhone Dev

JJW009 wrote:
The count will go up until they stop counting. That's the way counting works.


Doodle Sub!
Game Of Life

Image Image


Fri Feb 11, 2011 11:39 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 9:40 pm
Posts: 5288
Location: ln -s /London ~
Reply with quote
Remembered this morning I hadn't posted here. Java, like C, uses call-by-value for all methods. For all non-basic datatypes, though, this is effectively call-by-reference, as when you declare & define a non-basic var as in
Code:
MyClass class = new MyClass();

you effectively allocate and initialise the memory for class, but the var class actually holds the equivalent of a C-style pointer, so the type MyClass is more equivalent to being MyClass* in C-parlence. In a similar vein, array variables actually contain pointers to the array (in the same way as in C).

_________________
timark_uk wrote:
Gay sex is better than no sex

timark_uk wrote:
Edward Armitage is Awesome. Yes, that's right. Awesome with a A.


Thu Feb 17, 2011 10:33 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 8 posts ] 

Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.