Composition syntax | CodeGuru

Composition syntax

Bruce Eckel’s Thinking in Java Contents | Prev | Next Until now, composition has been used quite frequently. You simply place object handles inside new classes. For example, suppose you’d like an object that holds several String objects, a couple of primitives and an object of another class. For the non-primitive objects, just put handles […]

Written By
CodeGuru Staff
CodeGuru Staff
Mar 1, 2001
3 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Until


now, composition has been used quite frequently. You simply place object


handles inside new classes. For example, suppose you’d like an object


that holds several


String

objects, a couple of primitives and an object of another class. For the


non-primitive objects, just put handles inside your new class, and for the


primitives just define them inside your class: (See page


97

if you have trouble executing this program.)

//: SprinklerSystem.java
// Composition for code reuse
package c06;
 
class WaterSource {
  private String s;
  WaterSource() {
    System.out.println("WaterSource()");
    s = new String("Constructed");
  }
  public String toString() { return s; }
}
 
public class SprinklerSystem {
  private String valve1, valve2, valve3, valve4;
  WaterSource source;
  int i;
  float f;
  void print() {
    System.out.println("valve1 = " + valve1);
    System.out.println("valve2 = " + valve2);
    System.out.println("valve3 = " + valve3);
    System.out.println("valve4 = " + valve4);
    System.out.println("i = " + i);
    System.out.println("f = " + f);
    System.out.println("source = " + source);
  }
  public static void main(String[] args) {
    SprinklerSystem x = new SprinklerSystem();
    x.print();
  }
} ///:~ 

One


of the methods defined in


WaterSource

is


special:


toString( )

.


You will learn later that every non-primitive object has a

toString( )
method, and it’s called in special situations when the compiler wants a
String
but it’s got one of these objects. So in the expression:
System.out.println("source
= " + source);

the


compiler sees you trying to add a


String

object (


“source
= “

)


to a


WaterSource

.


This doesn’t make sense to it, because you can only “add” a


String

to another


String

,


so it says “I’ll turn


source

into a


String

by calling


toString( )

!”


After doing this it can combine the two


String

s


and pass the resulting


String

to


System.out.println( )

.


Any time you want to allow this behavior with a class you create you need only


write a


toString( )

method.

At


first glance, you might assume – Java being as safe and careful as it is


– that the compiler would automatically construct objects for each of the


handles in the above code, for example calling the default constructor for


WaterSource

to initialize


source

.


The output of the print statement is in fact:

valve1 = null
valve2 = null
valve3 = null
valve4 = null
i = 0
f = 0.0
source = null

Primitives


that are fields in a class are automatically

initialized
to zero, as noted in Chapter 2. But the object handles are initialized to
null,
and if you try to call methods for any of them you’ll get an exception.
It’s actually pretty good (and useful) that you can still print them out
without throwing an exception.

It


makes sense that the compiler doesn’t just create a default object for


every handle because that would incur unnecessary overhead in many cases. If


you want the handles initialized, you can do it:

  1. At
    the point the objects are defined. This means that they’ll always be
    initialized before the constructor is called.
  2. In
    the constructor for that class
  3. Right
    before you actually need to use the object. This can reduce overhead, if there
    are situations where the object doesn’t need to be created.

All


three approaches are shown here:

//: Bath.java
// Constructor initialization with composition
 
class Soap {
  private String s;
  Soap() {
    System.out.println("Soap()");
    s = new String("Constructed");
  }
  public String toString() { return s; }
}
 
public class Bath {
  private String
    // Initializing at point of definition:
    s1 = new String("Happy"),
    s2 = "Happy",
    s3, s4;
  Soap castille;
  int i;
  float toy;
  Bath() {
    System.out.println("Inside Bath()");
    s3 = new String("Joy");
    i = 47;
    toy = 3.14f;
    castille = new Soap();
  }
  void print() {
    // Delayed initialization:
    if(s4 == null)
      s4 = new String("Joy");
    System.out.println("s1 = " + s1);
    System.out.println("s2 = " + s2);
    System.out.println("s3 = " + s3);
    System.out.println("s4 = " + s4);
    System.out.println("i = " + i);
    System.out.println("toy = " + toy);
    System.out.println("castille = " + castille);
  }
  public static void main(String[] args) {
    Bath b = new Bath();
    b.print();
  }
} ///:~ 

Note


that in the


Bath

constructor


a statement is executed before any of the initializations take place. When you


don’t initialize at the point of definition, there’s still no


guarantee that you’ll perform any initialization before you send a


message to an object handle – except for the inevitable run-time exception.

Here’s


the output for the program:

Inside Bath()
Soap()
s1 = Happy
s2 = Happy
s3 = Joy
s4 = Joy
i = 47
toy = 3.14
castille = Constructed

When


print( )

is called it fills in


s4

so that all the fields are properly initialized by the time they are used.


Contents

|

Prev

|

Next
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.