Object References
Objects An array is a collection of values, all of the same type An object is a collection of values, which may be of different types –Actually, there’s more to an object than just values, but that’s all we need to consider right now Example: class Person { String name; boolean male; int age; int phoneNumber; } Notice that different kinds of objects typically take up different amounts of space in the computer
What this talk is about We’re going to discuss how objects are stored in computer memory You might think this doesn’t matter to you, because Java just automatically does all the work of finding a place for objects and putting them there –You would be wrong A lot of things involved in creating and manipulating objects are just plain mysterious unless you know what is going on “under the hood”
Computer memory organization A bit is a single on/off, yes/no, 0 / 1 value A byte is eight consecutive bits Computer memory is a numbered sequence of bytes, starting at zero –It is impossible for a memory location to be “empty”--bits are always either on or off The number associated with a byte is called its address A 000B Addresses are binary numbers (usually written as hexadecimal), but this isn’t really relevant to the discussion Larger computer systems might address words rather than bytes, where a word is some larger number of bits (such as 32 or 64)
Primitives in memory When you declare a primitive variable, you allocate space in memory for it A byte requires one byte of memory Hence, every variable has an address Address 0000 is never used A 000B char c; byte b; int i; An int requires four consecutive bytes of memory A char requires two consecutive bytes of memory
Objects in memory When you declare an object variable, Java does not know how much space the object needs--so it can’t allocate space for it It doesn’t know how much space is needed until you assign an object to the variable Instead, what Java does is allocate space for a pointer to the object –A pointer is a variable that holds an address –A pointer requires four consecutive bytes –The pointer is initially null ( 0000 ) Later, when you assign an actual object to the variable, what Java does is to make the pointer “point to” (hold the address of) the memory occupied by the object A 000B ?
Declaring and creating objects Person p = new Person("John"); Person p allocates space to hold a reference (pointer) to a Person p: new Person("John") allocates space for the actual Person, and initializes it "John"07A3 The assignment makes p refer to the new Person 07A3
Pointers and references Java uses references rather than pointers Both mean: A variable that holds an address –You can follow or dereference either one to get to the thing that it points to –You can assign either to a variable of the correct type But you can do more with pointers: –You can treat a pointer as an integer and do arithmetic to get a new pointer –Pointers can point to anything; references refer to known objects Consequences: –Pointers are much more flexible –References allow the computer to do more for you –90% of the serious errors in C and C++ programs are pointer errors
Consequences I: Assignment When you assign to a primitive variable, you get a copy of the value Hence, two object variables can refer to the same object –You can think of them as aliases of each other –If you change the object pointed to by one of them, you are changing the same object pointed to by the other 24 x 3 y y = x; 24 b a John Smith true b = a; a.age++; 24 When you assign to an object variable, you get a copy of the reference
Consequences II: parameters We call a method like this: result = add( 3, 5 ) ; Here’s the method: int add ( int number1, int number2 ) { int sum = number1 + number2 ; return sum ; } Actual parameter values are copied into formal parameters Formal parameters are used in method A result is returned
Primitive parameters are copied in int m = 3; int n = 5; result = add( m, n ) ; int add ( int number1, int number2 ) { while (number1 > 0) { number1--; number2++; } return number2 ; } The values of m and n (that is, 3 and 5) are copied to the formal parameters Changing number1 and number2 does not affect m and n This is call by value The value of number2 is returned, but the variable number2 is thrown away
Object references are copied in Person p = new Person("John"); changeName( p ); void changeName(Person per ) { per.name = "Jack"; } This means that p and per refer to the same object! This is call by reference p holds a reference to a Person "John" It is the reference that is copied in, not the Person p is not changed, but changes made to the object referenced by per remain changed when the method returns "Jack" per.name = "Jack";
Consequences III: final When you declare a variable to be final, you cannot change its value: final int speedLimit = 65; speedLimit = 70; // illegal! The value of an object variable is the address (reference) it contains, not the object itself: final Person president = new Person("George Bush"); president = new Person("Al Gore"); // illegal president.age = president.age + 1; // legal! president.name = "Al Gore"; // legal!
Consequences IV: NullPointerException When you declare an object variable, but before you assign it a value, it has the value null ( 0000 ) null is a legal value for any object variable –You can test if a variable has value null –You can assign null like any other value –You can not use the referenced object, because there isn’t any! Example: Person clerk; clerk.name = "John Smith"; // NullPointerException
Consequences V: Equality When you test two primitives for equality, you are testing their values Hence, a == b, but a != c For Strings you can use the equals method, s1.equals(s2), but for other kinds of objects it isn’t so simple 24 x y When you test two objects for equality, you are testing their references b a John Smith true c John Smith true
Arrays Arrays are objects! int[ ] scores; scores[0] = 76; // NullPointerException int[ ] testResults = new int[125]; testResults[0] = 98; int[ ] results = testResults; System.out.println(results[0]); // prints 98 int[ ] numbers = new int[10]; System.out.println(numbers[5]); // prints 0 (why?) Person[ ] people = new Person[10]; System.out.println(people[5]); // prints null (why?) System.out.println(people[5].name); // NullPointerException
The End