Class and object initialization in Java
in Java must be initialized before they are used. You previously learned that class fields are initialized to default values when classes are loaded and that objects are initialized via constructors, but there is more to initialization. Java's features for initializing classes and objects.
Initializing classes
Before we explore Java's support for class initialization, let's recap the basics of Java initialization
Initializing class fields to default values
class SomeClass
{
static boolean b;
static byte by;
static char c;
static double d;
static float f;
static int i;
static long l;
static short s;
static String st;
}
Listing 1 declares class
SomeClass
. This class declares nine fields of types boolean
, byte
, char
, double
, float
, int
, long
,short
, and String
. When SomeClass
is loaded, each field's bits are set to zero, which you interpret as follows:
false
0
\u0000
0.0
0.0
0
0
0
null
The previous class fields were implicitly initialized to zero. However, you can also explicitly initialize class fields by directly assigning values to them, as shown in Listing 2.
Listing 2. Initializing class fields to explicit values
class SomeClass
{
static boolean b = true;
static byte by = 1;
static char c = 'A';
static double d = 2.0;
static float f = 3.0f;
static int i = 4;
static long l = 5000000000L;
static short s = 20000;
static String st = "abc";
}
Each assignment's value must be type-compatible with the class field's type. Each variable stores the value directly, with the exception of
st
. Variable st
stores a reference to aString
object that contains abc
.Referencing previously declared and subsequently declared class fields
When initializing a class field, it's legal to initialize it to the value of a previously initialized class field. For example, Listing 3 initializes
y
to x
's value. Both fields are initialized to 2
.Listing 3. Referencing a previously declared field
class SomeClass
{
static int x = 2;
static int y = x;
public static void main(String[] args)
{
System.out.println(x);
System.out.println(y);
}
}
However, the reverse is not legal: you cannot initialize a class field to the value of a subsequently declared class field. The Java compiler outputs
illegal forward reference
when it encounters this scenario. Consider Listing 4.Listing 4. Attempting to reference a subsequently declared field
class SomeClass
{
static int x = y;
static int y = 2;
public static void main(String[] args)
{
System.out.println(x);
System.out.println(y);
}
The compiler will report
illegal forward reference
when it encounters static int x = y;
. This is because source code is compiled from the top down, and the compiler hasn't yet seen y
. (It would also output this message if y
wasn't explicitly initialized.)Introducing class initialization blocks
You might want to perform complex class-based initialization after a class has been loaded and before any objects are created from that class (assuming that the class isn't a utility class). You can use a class initialization block for this task.
A class initialization block is a block of statements preceded by the
static
keyword that's introduced into the class's body. When the class loads, these statements are executed. Consider Listing 5.Listing 5. Initializing arrays of sine and cosine values
class Graphics
{
static double[] sines, cosines;
static
{
sines = new double[360];
cosines = new double[360];
for (int i = 0; i < sines.length; i++)
{
sines[i] = Math.sin(Math.toRadians(i));
cosines[i] = Math.cos(Math.toRadians(i));
}
}
}
Listing 5 declares a
Graphics
class that declares sines
and cosines
array variables. It also declares a class initialization block that creates 360-element arrays whose references are assigned to sines
and cosines
. It then uses a for
statement to initialize these array elements to the appropriate sine and cosine values, by calling the Math
class's sin()
and cos()
methods. (Math
is part of Java's standard class library. I'll discuss this class and these methods in a future article.)Combining class field initializers and class initialization blocks
You can combine multiple class field initializers and class initialization blocks in an application. Listing 6 provides an example.
Listing 6. Performing class initialization in top-down order
class MCFICIB
{
static int x = 10;
static double temp = 98.6;
static
{
System.out.println("x = " + x);
temp = (temp - 32) * 5.0/9.0; // convert to Celsius
System.out.println("temp = " + temp);
}
static int y = x + 5;
static
{
System.out.println("y = " + y);
}
Object
After a class has been loaded and initialized, you'll often want to create objects from the class. As you learned in my recent introduction to programming with classes and objects, you initialize an object via the code that you place in a class's constructor. Consider Listing 7.
Listing 7. Initializing an object via a constructor
class City
{
private String name;
int population;
City(String name, int population)
{
this.name = name;
this.population = population;
}
@Override
public String toString()
{
return name + ": " + population;
}
public static void main(String[] args)
{
City newYork = new City("New York", 8491079);
System.out.println(newYork); // Output: New York: 8491079
}
}
Listing 7 declares a City
class with name
and population
fields. When a City
object is created, the City(String name, int population)
constructor is called to initialize these fields to the called constructor's arguments. (I've also overridden Object
's public String toString()
method to conveniently return the city name and population value as a string. System.out.println()
ultimately calls this method to return the object's string representation, which it outputs.)
Before the constructor is called, what values do name
andpopulation
contain? You can find out by insertingSystem.out.println(this.name); System.out.println(this.population);
at the start of the constructor. After compiling the source code (javac City.java
) and running the application (java City
), you would observe null
for name
and 0
for population
. The new
operator zeroes an object's object (instance) fields before executing a constructor.
As with class fields, you can explicitly initialize object fields. For example, you could specify String name = "New York";
or int population = 8491079;
. However, there's usually nothing to gain by doing this, because these fields will be initialized in the constructor. The only benefit that I can think of is to assign a default value to an object field; this value is used when you call a constructor that doesn't initialize the field:
int numDoors = 4; // default value assigned to numDoors
Car(String make, String model, int year)
{
this(make, model, year, numDoors);
}
Car(String make, String model, int year, int numDoors)
{
this.make = make;
this.model = model;
this.year = year;
this.numDoors = numDoors;
}
For Java beginner's
Start from Class and object
Credit goes to java world
No comments:
Post a Comment