CSC 207 Grinnell College Fall, 2018
 
Algorithms and Object-Oriented Design
 

References, Autoboxing, and Unboxing

Summary

This lab provides background and experience with primitive types, references to objects, autoboxing, and autounboxing in Java.

Acknowledgment

Much of this lab is edited from materials by Samuel Rebelsky:

Reading

Please read the following as preparation for this lab:

Variables for Primitive Types, Objects, and Immutable Objects

As noted in the Reading on Reference Values in Java,

  1. Copy the following two Java classes to your account for inclusion in a references package.

    Compile and run Experiments1.java and answer the following:

    1. Do int variables int1 and int2 represent two distinct memory locations, or do they refer to the same memory location? Explain how you know.
    2. What does the statement int int2 = int1 do regarding memory allocation and processing? To what extent does this experiment in Java seem similar to or different from your experience in C?
    3. Does the statement int1 += 5 change both int1 and int2, or just int1? Explain why this result is obtained.
    4. Do Tally variables tally1 and tally2 represent two distinct objects and memory locations, or do they refer to the same object? Explain how you know.
    5. In the Tally class, comment out the definition of toString, so that the compiler will use a default specification (giving the object's address). Does this experiment support your conclusion in Step d? Explain briefly.
    6. Restore the toString method in Tally for this and subsequent steps. What does the statement Tally tally2 = tally1 do regarding memory allocation and processing? To what extent does this experiment in Java seem similar to or different than your experience in C?
    7. Does the statement tally.tally () change both tally1 and tally2 or just tally1? Explain why this result is obtained.
    8. Moving on to integer1 and integer2, both of these refer to objects, such as tally1 and tally2.
      • Do you think these refer to the same object or to different objects?
      • What do you think the statement integer1 += 5 means, as an operation for an object referenced by integer1?
      • Does a change in integer1 also change integer2, analogous to tally1 and tally2?

      Note: You may find it takes the rest of this lab to explain why Java gives this result!

Normal Calling Mechanisms

  1. Copy Experiments2.java to your references package in Java.

    Consider the following instructions.

    System.out.println("square(bigi): " + square(bigi));
    System.out.println("sqr(littlei): " + sqr(littlei));
    System.out.println("bracket(str): " + bracket(str));
    System.out.println("bigSum(bigvals): " + bigSum(bigvals));
    System.out.println("littleSum(littlevals): " + littleSum(littlevals));
    System.out.println();
    

    In each case, the method (Java's jargon for function) is declared specifying a parameter of a specific type, and the call to the method supplies exactly this type of parameter.

    1. Do you expect the Java compiler to accept these instructions? Why or why not?
    2. If the Java compiler accepts these instructions, what output would you expect to see when you run the program?
    3. Check your answers to a and b experimentally.

Matching Primitives (e.g., int) or Wrapper Classes (e.g., Integer) with String Types

  1. Add the following instructions to the main method of the Experiments2.java class.

    System.out.println("bigi: " + bigi);
    System.out.println("littlei: " + littlei);
    System.out.println();
    

    These examples illustrate how Java handles the primitive int and the wrapper class Integer when a String is expected.

    1. Method bracket expects a String object as parameter. What happens when the main tries to pass parameters Integer bigi or the int littlei into bracket as a parameter that is supposed to be a String?
    2. Do you expect the Java compiler to accept these instructions? Why or why not?
    3. If the Java compiler accepts these instructions, what output would you expect to see when you run the program?
    4. Check your answers to a, b, and c experimentally.
    5. What, if anything, does this exercise suggest about the use of primitives or objects when a String is expected?
  2. With this background, consider the following instructions.

    System.out.println("parenthesize(str): " + parenthesize(str));
    System.out.println("parenthesize(bigi): " + parenthesize(bigi));
    System.out.println("parenthesize(littlei): " + parenthesize(littlei));
    System.out.println();
    
    1. Do you expect the Java compiler to accept these instructions? Why or why not?
    2. If the Java compiler accepts these instructions, what output would you expect to see when you run the program?
    3. Check your answers to a and b experimentally.

Basic Autoboxing and Unboxing

  1. These examples illustrate the mixing of primitive int variables with objects from the wrapper class Integer. Oracle's Java Tutorial on Autoboxing and Unboxing provides some basic background.

    Consider the following instructions.

    System.out.println("square(littlei): " + square(littlei));
    System.out.println("sqr(bigi): " + sqr(bigi));
    System.out.println();
    
    1. Why do you think the Java compiler allows these instructions?
      • How is it possible for an int to be passed to square which expects an Integer?
      • How is it possible for an Integer to be passed to sqr which expects an int?
    2. Review the definition of Java's Integer class. What code do you think the Java compiler inserts when an int is passed to square?
    3. Again reviewing the definition of of Java's Integer class, what code you do think the Java compiler inserts when an Integer is passed to sqr?
  2. With this background on autoboxing and unboxing, consider the following procedure.

    /**
     * Square an Integer, using boxing/unboxing.
     */
    public static Integer
    sq(Integer x)
    {
      return x * x;
    } // sq(Integer)
    

    Consider also the following instructions, which will get added to main.

    System.out.println("sq(bigi): " + sq(bigi));
    System.out.println("sq(littlei): " + sq(littlei));
    System.out.println();
    
    1. Do you expect the Java compiler to accept this new procedure and the corresponding instructions? Why or why not?
    2. If the Java compiler accepts these instructions, how do you think the Java compiler is interpreting the statement return x * x? That is, using the definition of of Java's Integer class, what code do you think the Java compiler is adding behind the scenes?

Boxing and Arrays

The past examples illustrate how autoboxing and unboxing allows a Java compiler to automatically convert between Java's primitive types (e.g., int) and the corresponding wrapper classes (e.g., Integer). The next experiments explore arrays of primitives and the corresponding wrapper classes.

  1. Consider the following instructions.

    System.out.println("littleSum(bigvals): " + littleSum(bigvals));
    System.out.println("bigSum(littlevals): " + bigSum(littlevals));
    System.out.println();
    
    1. Do you expect the Java compiler to accept these instructions? Why or why not?
    2. If the Java compiler accepts these instructions, what output would you expect to see when you run the program?
    3. Check your answers to a and b experimentally.
    4. What, if anything, does this exercise suggest about autoboxing/unboxing or related issues?

What about null?

The readings note that one potential issue with autoboxing and unboxing is that we have to deal with null as a special case.

  1. As a first experiment with a null value, consider the following instructions, in which a null is used in a function designed to square an Integer object.

    Integer ex8 = null;
    System.out.println("square(ex8): " + square(ex8));
    System.out.println();
    
    1. Do you expect the Java compiler to accept these instructions? Why or why not?
    2. If the Java compiler accepts these instructions, what output would you expect to see when you run the program?
    3. Check your answers to a and b experimentally.
    4. What, if anything, does this exercise suggest about autoboxing/unboxing or related issues?
  2. Next consider the following instructions, in which a null is passed for a String object.

    String ex9 = null;
    System.out.println("bracket(ex9): " + bracket(ex9));
    System.out.println();
    
    1. Do you expect the Java compiler to accept these instructions? Why or why not?
    2. If the Java compiler accepts these instructions, what output would you expect to see when you run the program?
    3. Check your answers to a and b experimentally.
    4. What, if anything, does this exercise suggest about autoboxing/unboxing or related issues?
  3. For another experiment with a null value, consider the following instructions, in which a null is used for an array of objects.

    String ex10 = null;
    System.out.println("parenthesize(ex10): " + parenthesize(ex10));
    System.out.println();
    
    1. Do you expect the Java compiler to accept these instructions? Why or why not?
    2. If the Java compiler accepts these instructions, what output would you expect to see when you run the program?
    3. Check your answers to a and b experimentally.
    4. What, if anything, does this exercise suggest about autoboxing/unboxing or related issues?

Immutable Objects

Some Java objects are immutable — once created, they cannot be changed. The following readings provide some basic background:

  1. Review the specifications for Java's Integer class.

    1. What methods are available to change the value of an Integer object?
    2. Back in Step1, code included the following
      Integer integer1 = new Integer (2)
      integer1 += 5;
      
      Interpret the second line, now that you know that Integer objects are immutable. What code do you think the compiler inserts behind the scenes to make this code work?
  2. Review the specifications for Java's String class.

    1. What methods are available to change the value of an String object?
    2. Various methods within the String class return substrings, change a character of a string, or otherwise produce a modification of the original String object. Do any of these methods change the original object, or do they always create a new object? Explain briefly.

This document is available on the World Wide Web as

http://www.walker.cs.grinnell.edu/courses/207.sp15/labs/lab-references-boxing.shtml

created 9 January 2015 by Henry M. Walker
revised 12 January 2015 by Henry M. Walker
Valid HTML 4.01! Valid CSS!
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.