Constructing Objects

     

When you define a class, you can define one or more constructors for it. A constructor provides a way of creating (constructing) an instance of its class.

When you use the new keyword to create an object, you are calling the constructor of that class whose argument list matches the arguments provided in the call.

The following code calls the default (no-arg) constructor for the JButton class:

 

 JButton btnSave = new JButton(); 

Constructors are special methods that must match the names of the classes in which they are defined, and which have no return type. They are used to control how objects are created, and often, to initialize fields to the values specified in the argument list.

When you run the preceding code, the runtime determines if there is sufficient memory space to create the object and its data. If there is not enough space, the runtime tries to find any candidates for garbage collection. The garbage collector destroys items with no references, because they can no longer be used in a program's life. If there is still not enough space, an OutOfMemoryError is thrown.

 

 package net.javagarage; public Employee {   private String name;   public Employee(String nameIn) {      this.name = nameIn;   } } 

graphics/fridge_icon.jpg

FRIDGE

We haven't discussed superclasses (a.k.a. parent classes) yet. But for now, just know that the java object tree is hierarchical. A class can extend another class, which means that it can inherit its non-private data and functionality. Every Java class in the world automatically inherits from java.lang.object. That means that any class you write will be able to do what Java objects do. It means that any class you write will inherit the methods defined in that class, such as equals, hashCode, wait, and notify.


The code in bold represents the constructor. It has no return type and its name matches exactly the name of the class.

It accepts one argument, a String. The field name is then initialized to the value of the parameter nameIn . The superclass constructor with a matching signature is called. Then the constructor exits and the object is ready for use. Let's see how this works.

Constructors.java

 

 package net.javagarage.demo.classes; /**  * Demos use of constructors, and how  * they interact with superclass constructors.  * @author eben hewitt  */ public class Constructors {       public Constructors() {             System.out.println("Superclass constructor!");       }       public static void main(String[] args) {             //what does this print?             //in what order?             SubClass sa = new SubClass();       } } class SubClass extends Constructors {       //overriding the no-arg constructor       public SubClass() {             System.out.println("Subclass constructor!");       } } 

So how many constructors are called in the preceding code? Here is a misleading clue: the code outputs the following:

 

 Superclass constructor! Subclass constructor! 

The answer is three, because every class in Java is a subclass of java.lang.object ”so the matching constructor in the object class gets called too. When you construct an object, all matching constructors are called down the hierarchy.

No-Arg Constructors and Overloaded Constructors

The constructor called in the preceding code is called the no-arg constructor. This means that it doesn't accept any arguments. You can explicitly write a no-arg constructor in your class definition. If you don't, a no-arg constructor is provided for you that does nothing but create an empty object of the specified type. That constructor is called the default constructor.

The default constructor is not provided if you provide any constructor definition of your own. If you want to provide a no-arg constructor, you have to define it yourself. Here's how:

 

 package net.javagarage; public Employee {   private String name;   public Employee() {}   public Employee(String name) {      this.name = name;   } } 

The Employee class here defines a public, no-arg constructor. Because it provides a constructor that accepts a String argument, which it assigns to the name field, it must explicitly define a no-arg constructor if you want users of your Employee class to ever be able to create Employees without also initializing the name field concurrently.

After an object has been created, its variables must be initialized (remember, that's the second purpose of constructors).

Although you can create a JButton using the no-argument constructor, as we did earlier, the JButton class defines several other constructors (remember, classes can define as many constructors as they want ”or none). One of the other constructors takes a String argument that initializes the field that represents the text printed on the button. So, calling the following constructor:

 

 JButton btnSave = new JButton("Save"); 

kills two birds with one stone.

You don't have to call the setText(String s) method now, because the constructor that accepts a String argument has already done that for you. If there is not a constructor defined that matches the argument list that you try to use to create an object, a NoClassDefFoundError is thrown.

To overload a constructor, just make another one that has a different argument list than any other constructor in that class, just like overloading a regular method. There are many different overloaded constructors defined in the Java API. The String class, for example, has 14 constructors.

You can create a constructor with a variable-length argument list, as shown here.

VarArgConstructor.java
 

 package net.javagarage.demo;    //demonstrates ability to create    //constructor with variable length arguments public class VarArgConstructor {    //vararg constructor    public VarArgConstructor(Integer...ar){       System.out.println("Object created!");       for (Integer i : ar) {           System.out.println(i);       }    }    public VarArgConstructor(Integer i, Integer j){       System.out.println("Constructor with two Ints         called!");    }    public static void main(String...args) {       VarArgConstructor va = new               VarArgConstructor(1,2);    } } 

Note that the correct constructor is called in the preceding class. If you replace the object creation statement with one that passes three or five int s into the constructor, the vararg constructor will be called. Because we pass in two int s, "Constructor with two Ints called!" is printed.

Private Constructors

You can define a private constructor as well. But just like in methods, the private access modifier indicates that that constructor can only be called from within the class itself. This is often used to purposefully disallow clients of the class to create instances of the class. For more about how and why to do this, visit the Singleton pattern, discussed in the "Design Patterns" chapter in More Java Garage .

Calling Other Constructors with this

The Java keyword this is used to refer to the current instance of a class. It operates like the VB Me keyword. But there is another use for this . Writing overloaded constructors could easily mean repeating the same code over and over. To save you from having to do that, you can call this as you would a method, and the invocation will refer to a constructor defined in your class that matches the parameter list.

If you invoke another constructor within the same class using this , it must be the very first thing you do in your constructor.

ThisConstructor.java
 

 package net.javagarage.demo; public class ThisConstructor {    private boolean isInitialized;    private String name;    private int theID; public ThisConstructor() {    isInitialized = true;    System.out.println("no-arg called"); } public ThisConstructor(int theID) {    super();    this.theID = theID; } public ThisConstructor(int theID, String name) {    //call constructor that takes int    this(theID);    //set the string value    this.name = name;    System.out.println("int, String arg called"); } public static void main(String[] ar) {   ThisConstructor ts = new ThisConstructor(555,                            "Mr. Ed");    } } 

The output is

 

 no-arg called int, String arg called 

Static Constructors

This is kind of a misnomer. You don't get a static constructor by adding the static keyword to a regular constructor. You just write the keyword static and then curly braces. Inside the curly braces, write the code you want to execute.

Static constructors inside the class that contains the main method are executed even before the main method, when the class is initially loaded in the classloader.

You can define multiple static constructors. They will be executed in the order in which they appear in source code . The following code shows the order in which the constructors are executed.

Static Constructors.java
 

 package net.javagarage.demo.classes; /**  * Demo order in which constructors are called.  * @author eben hewitt  */ public class StaticConstructor { static {   System.out.println("Inside static constructor ONE."); } //regular no-arg constructor public StaticConstructor(){   System.out.println("Inside regular constructor."); } public static void main(String[] args) {   StaticConstructor c = new StaticConstructor();   System.out.println("Inside main."); } static {   System.out.println("Inside static constructor TWO."); } } 

And here's the output:

 

 Inside static constructor ONE. Inside static constructor TWO. Inside regular constructor. Inside main. 

Static constructors are rarely used in regular business application programming. They are used for loading native code, discussed in detail in More Java Garage .



Java Garage
Java Garage
ISBN: 0321246233
EAN: 2147483647
Year: 2006
Pages: 228
Authors: Eben Hewitt

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net