Showing posts with label Static variable. Show all posts
Showing posts with label Static variable. Show all posts

Tuesday, January 25, 2011

Chapter 13: Statics

Static is one of the most important and powerful keywords in the java programming language. It can alter the behavior of variables and methods. The purpose of this chapter is to take a detailed look at this feature.

Static Variables and Methods

The static modifier has such a profound impact on the behavior of a method or variable that we’re treating it as a concept entirely separate from the other modifiers. To understand the way a static member works, we’ll look first at a reason for using one. Imagine you’ve got a utility class with a method that always runs the same way; its sole function is to return, say, a random number. It wouldn’t matter which instance of the class performed the method—it would always behave exactly the same way. In other words, the method’s behavior has no dependency on the state (instance variable values) of an object. So why, then, do you need an object when the method will never be instance-specific? Why not just ask the class itself to run the method?

Let’s imagine another scenario: Suppose you want to keep a running count of all instances instantiated from a particular class. Where do you actually keep that variable? It won’t work to keep it as an instance variable within the class whose instances you’re tracking, because the count will just be initialized back to a default value with each new instance. The answer to both the utility-method-always-runs-the-same scenario and the keep-a-running-total-of-instances scenario is to use the static modifier. Variables and methods marked static belong to the class, rather than to any particular instance. In fact, you can use a static method or variable without having any instances of that class at all. You need only have the class available to be able to invoke a static method or access a static variable. static variables, too, can be accessed without having an instance of a class. But if there are instances, a static variable of a class will be shared by all instances of that class; there is only one copy.

The following code declares and uses a static counter variable:

class Car {
static int CarCount = 0; // Declare and initialize
// static variable
public Car() {
CarCount += 1; // Modify the value in the constructor
}
public static void main (String [] args) {
new Car();
new Car();
new Car();
System.out.println("Car count is now " + CarCount);
}
}

In the preceding code, the static CarCount variable is set to zero when the Car class is first loaded by the JVM, before any Car instances are created! (By the way, you don’t actually need to initialize a static variable to zero; static variables get the same default values instance variables get.) Whenever a Car instance is created, the Car constructor runs and increments the static CarCount variable. When this code executes, three Car instances are created in main(), and the result is

Car count is now 3

Now imagine what would happen if CarCount were an instance variable (in other words, nonstatic):
class Car {
int CarCount = 0; // Declare and initialize
// instance variable
public Car() {
CarCount += 1; // Modify the value in the constructor
}
public static void main (String [] args) {
new Car();
new Car();
new Car();
System.out.println("Car count is now " + CarCount);
}
}

When this code executes, it should still create three Car instances in main(), but the result is...a compiler error! We can’t get this code to compile, let alone run.
Car.java:11: nonstatic variable CarCount cannot be referenced

from a static context
System.out.println("Car count is " + CarCount);
^
1 error

The JVM doesn’t know which Car object’s CarCount you’re trying to access. The problem is that main() is itself a static method, and thus isn’t running against any particular instance of the class, rather just on the class itself. A static method can’t access a nonstatic (instance) variable, because there is no instance! That’s not to say there aren’t instances of the class alive on the heap, but rather that even if there are, the static method doesn’t know anything about them. The same applies to instance methods; a static method can’t directly invoke a nonstatic method. Think static = class, nonstatic = instance. Making the method called by the JVM (main()) a static method means the JVM doesn’t have to create an instance of your class just to start running code.

Exam Tip:
One of the mistakes most often made by new Java programmers is attempting to access an instance variable (which means nonstatic variable) from the static main() method (which doesn’t know anything about any instances, so it can’t access the variable). The following code is an example of illegal access of a nonstatic variable from a static method:
class Bad {
int x = 3;
public static void main (String [] args) {
System.out.println("x is " + x);
}
}
Understand that this code will never compile, because you can’t access a nonstatic (instance) variable from a static method. Just think of the compiler saying, “Hey, I have no idea which Bad object’s x variable you’re trying to print!” Remember, it’s the class running the main() method, not an instance of the class.

Of course, the tricky part for the exam is that the question won’t look as obvious as the preceding code. The problem you’re being tested for—accessing a nonstatic variable from a static method—will be buried in code that might appear to be testing something else. For example, the preceding code would be more likely to appear as
class Bad {
int x = 3;
float y = 4.3f;
public static void main (String [] args) {
for (int z = x; z < ++x; z--, y = y + z) // complicated looping and branching code } } So while you’re trying to follow the logic, the real issue is that x and y can’t be used within main(), because x and y are instance, not static, variables! The same applies for accessing nonstatic methods from a static method. The rule is, a static method of a class can’t access a nonstatic (instance) method or variable of its own class.





Accessing Static Methods and Variables

Since you don’t need to have an instance in order to invoke a static method or access a static variable, then how do you invoke or use a static member? What’s the syntax? We know that with a regular old instance method, you use the dot operator on a reference to an instance:

class Car {
int CarSize = 0;
public int getCarSize() {
return CarSize;
}
public Car(int s) {
CarSize = s;
}
public static void main (String [] args) {
Car f = new Car(25);
System.out.println(f.getCarSize()); // Access instance
// method using f
}
}

In the preceding code, we instantiate a Car, assign it to the reference variable f, and then use that f reference to invoke a method on the Car instance we just created. In other words, the getCarSize() method is being invoked on a specific Car object on the heap.

But this approach (using a reference to an object) isn’t appropriate for accessing a static method, because there might not be any instances of the class at all! So, the way we access a static method (or static variable) is to use the dot operator on the class name, as opposed to using it on a reference to an instance, as follows:

class Car {
static int CarCount = 0; // Declare and initialize
// static variable
public Car() {
CarCount += 1; // Modify the value in the constructor
}
}

class TestCar {
public static void main (String [] args) {
new Car();
new Car();
new Car();
System.out.print("CarCount:"+Car.CarCount); //Access
// static variable
}
}

But just to make it really confusing, the Java language also allows you to use an object reference variable to access a static member:
Car f = new Car();
int Cars = f.CarCount; // Access static variable
// CarCount using f

In the preceding code, we instantiate a Car, assign the new Car object to the reference variable f, and then use the f reference to invoke a static method! But even though we are using a specific Car instance to access the static method, the rules haven’t changed. This is merely a syntax trick to let you use an object reference variable (but not the object it refers to) to get to a static method or variable, but the static member is still unaware of the particular instance used to invoke the static member. In the Car example, the compiler knows that the reference variable f is of type Car, and so the Car class static method is run with no awareness or concern for the Car instance at the other end of the f reference. In other words, the compiler cares only that reference variable f is declared as type Car.

Finally, remember that static methods can’t be overridden! This doesn’t mean they can’t be redefined in a subclass, but redefining and overriding isn’t the same thing. Let’s take a look at an example of a redefined (remember, not overridden), static method:

class Car {
static void drive() {
System.out.print("a ");
}
}
class Ferrari extends Car {
static void drive() { // it's a redefinition & not an override
System.out.print("d ");
}
public static void main(String [] args) {
Car [] a = {new Car(), new Ferrari(), new Car()};
for(int x = 0; x < a.length; x++) a[x].drive(); // invoke the static method } } Running this code produces the output: a a a Remember, the syntax a[x].drive() is just a shortcut (the syntax trick)...the compiler is going to substitute something like Car.drive() instead. This happens because the Array is of type Car and so the static method inside the Car class is used even though there is an instance of Ferrari in the list. Previous Chapter: Chapter 12 - Constructors and Instantiation

Next Chapter: Chapter 13 - Coupling & Cohesion

Saturday, January 1, 2011

Chapter 2: Declarations

Classes and Interfaces are the basis based on which the java programming universe revolves. Everything in Java is an object but an object is nothing but the runtime orientation of a class. In other words, an object is nothing but a class that is being executed.

Whenever you write any java code, it implicitly means that you are writing classes or interfaces. Within those classes, as you know, are variables and methods (plus a few other things). How you declare your classes, methods, and variables dramatically affects your code’s behavior

Source File Declaration Rules:

Before we dig into class declarations, let’s do a quick review of the rules associated with declaring classes, import statements, and package statements in a source file:
• There can be only one public class per source file.
• Comments can appear at the beginning or end of any line in the source code file; they are independent of any of the positioning rules discussed here.
• If there is a public class in a file, the name of the file must match the name of the public class. For example, a class declared as public class Rock { } must be in a source code file named Rock.java.
• If the class is part of a package, the package statement must be the first line in the source code file, before any import statements that may be present.
• If there are import statements, they must go between the package statement (if there is one) and the class declaration. If there isn’t a package statement, then the import statement(s) must be the first line(s) in the source code file. If there are no package or import statements, the class declaration must be the first line in the source code file.
• import and package statements apply to all classes within a source code file. In other words, there’s no way to declare multiple classes in a file and have them in different packages, or use different imports.
• A file can have more than one nonpublic class.
• Files with no public classes can have a name that does not match any of the classes in the file.

Now that we have taken a look at the rules for declaring a java source code file, let us get into the real thing about declaring classes.

Declaring Classes:

A Class can be declared with the following statement:

public class AnandsFirstclass {}

Irrespective of the fact that this class does not have any code, this piece of code when saved in a file called AnandsFirstclass.java compiles just fine. Here public is an access modifier (we will see access modifiers in greater detail in one of the subsequent chapters), class is the keyword that is used to specify that a class is being declared and AnandsFirstclass is the name of the class we are creating.

There are many different types of classes that you can create. Some of which are:
1. Final Classes – A class that cannot be inherited (Dont worry about inheritance just yet. We will look into it in full detail in one of the later chapters)
2. Normal Classes – The type of class that we declared a few lines back
3. Abstract Classes – A class that is similar to a normal class but that does not provide full functional behaviour by itself. It has to be subclassed/inherited in order to be used.

Abstract Classes in Detail:
An Abstract class is a special kind of class that cannot be instantiated. It has one or more methods which are not implemented in the class. These methods are declared abstract and they do not contain any code inside them.

Ex:
abstract class Parent {
public abstract String getSon();
public abstract String getDaughter();
....
....
//More methods that contain specific behaviour/code in them
}

The above is an abstract class “Parent” that has a lot of functionality but it has declared two abstract methods which have no code inside them. Any class that has one or more abstract methods has to be abstract. This abstract class cannot be instantiated.

i.e., the below piece of code will not work. The code will not even compile.

Parent object = new Parent();

Purpose of Abstract Classes:
Abstract classes are generally used where you want an amount of behaviour to be used by the class that extends the abstract class while at the same time giving options to the child class to provide a certain amount of behaviour itself.

A Child Class extending the Abstract Class:

public class Child extends Parent {
public String getSon() {
return “Sons Name”;
}

public String getDaughter(){
return “Daughters Name”;
}
...
... //Code specific to the Child class
}

Declaring Interfaces:

When you create an interface, you’re defining a contract for what a class can do, without saying anything about how the class will do it. Interfaces can be implemented by any class, from any inheritance tree. This lets you take radically different classes and give them a common characteristic.

Ex: You can create an interface Drivable which in effect means that it has the feature of being driven. Any class that implements this Drivable interface must provide an implementation of the drive() method can be driven. But how it will be driven is up to the classes to provide the implementation. Both a car and a bus can be driven but the how part is different. So the classes Car and Bus will implement this interface and provide their specific behavior about being driven.

Tip: An Interface is an 100% Abstract class

Comparison between an Abstract Class and an Interface:

While an abstract class can define both abstract and non-abstract methods, an interface can have only abstract methods. Another way interfaces differ from abstract classes is that interfaces have very little flexibility in how the methods and variables defined in the interface are declared. These rules are strict:

• All interface methods are implicitly public and abstract. In other words, you do not need to actually type the public or abstract modifiers in the method declaration, but the method is still always public and abstract. (You can use any kind of modifiers in the Abstract class)
• All variables defined in an interface must be public, static, and final—in other words, interfaces can declare only constants, not instance variables.
• Interface methods must not be static.
• Because interface methods are abstract, they cannot be marked final, strictfp, or native. (More on these modifiers later.)
• An interface can extend one or more other interfaces.
• An interface cannot extend anything but another interface.
• An interface cannot implement another interface or class.
• An interface must be declared with the keyword interface.

You must remember that all interface methods are public and abstract regardless of what you see in the interface definition.

Look out for questions where interface methods are declared with any combination of public, abstract, or no modifiers. For example, the following five method declarations, if declared within their own interfaces, are legal and identical!

void bbb();
public void bbb();
abstract void bbb();
public abstract void bbb();
abstract public void bbb();

whereas the below declarations wont compile:

The following interface method declarations won’t compile:
final void bbb(); // final and abstract can never be used
// together, and abstract is implied
static void bbb(); // interfaces define instance methods
private void bbb(); // interface methods are always public
protected void bbb(); // (same as above)

Declaring Variables in an Interface

We are allowed to declare variables in an interface. By default these variables would be constants because they would static and final. By placing the constants right in the interface, any class that implements the interface has direct access to the constants, just as if the class had inherited them.

You need to remember one key rule for interface constants. They must always be
public static final

Since the variables declared in an interface are by default public static and final, we need not mention them explicitly. But it is a good practice to do so to ensure that even novice programmers can understand the code you write.

Constructor Declarations:

In Java, objects are constructed. Every time you make a new object, at least one constructor is invoked. Every class has a constructor, although if you don’t create one explicitly, the compiler will build one for you.

Ex:
class Test {
public Test() { } // this is Test’s constructor

public void Test() { } // this is a badly named,
// but legal, method
}

If you see the example above, you would have realized that the constructor looks a lot like methods. Below are the main distinguishing factors between the constructor and normal methods:
1. The Constructor’s name is exactly the same as the name of the class
2. They do not have a return type (Please remember this. A Constructor cannot have a return type as part of the code)
3. Constructors cannot be static, abstract or final

Declaring Variables:

There are two types of variables in Java:
Primitives - A primitive variable can be one of eight types: char, boolean, byte, short, int, long, double, or float. Once a primitive has been declared, its primitive type can never change, although in most cases its value can change.
Reference variables - A reference variable is used to refer to (or access) an object. A reference variable is declared to be of a specific type and that type can never be changed.

We should remember that each of the primitive datatype has a particular range and by assigning values that are bigger than the size it can take would result in errors or loss of value and precision. Below are the data ranges of the primitive datatypes:

Primitive Data Type Ranges in Java
Data Type Bits Used Minimum Value Maximum Value
byte 8 -27 27 - 1
short 16 -215 215 -1
int 32 -231 231 -1
long 64 -263 263 -1
float 32 n/a n/a
double 64 n/a n/a
The range for these floating point numbers is difficult to determine and it is not required from the exam perspective as well. Booleans and char type variables do not have a range. Booleans can be either true or false and chars can be only one character in size Ex: “A” or “B” etc

Declaring Reference Variables:

Reference variables can be declared as static variables, instance variables, method parameters, or local variables. You can declare one or more reference variables, of the same type, in a single line

Variables can be declared in multiple places inside a class which determines what type of variable gets created. They are:

Instance Variables

Instance variables are defined inside the class, but outside of any method, and are only initialized when the class is instantiated. Instance variables are the fields that belong to each unique object.

Ex:
public class Test {
private String name = “Anand”;
private String country = “India”;
}

Here name and country are two instance variables where they would be a part of an object of the class Test. Since each variable is part of the class’s instance (object), they are called instance variables.
For the exam, you need to know that instance variables
• Can use any of the four access levels (which means they can be marked with any of the three access modifiers)
• Can be final
• Can be transient
• Cannot be abstract
• Cannot be synchronized
• Cannot be strictfp
• Cannot be native
• Cannot be static, because then they’d become class variables.

Static Variables or Class Variables:

The static modifier is used to create variables and methods that will exist independently of any instances created for the class. All static members exist before you ever make a new instance of a class, and there will be only one copy of a static member regardless of the number of instances of that class.

Things you can mark as static:
• Methods
• Variables
• A class nested within another class, but not within a method (more on this in Chapter 8).
• Initialization blocks

Things you can’t mark as static:
• Constructors (makes no sense; a constructor is used only to create instances)
• Classes (unless they are nested)
• Interfaces
• Method local inner classes
• Inner class methods and instance variables
• Local variables

Method Parameters:

These are variables that are declared as part of a methods declaration. These are arguments that will be used as part of the method.

Ex: public int add(int a, int b) {
return a + b;
}

Here a and be are the method parameters.

Local Variables:

These are variables that are declared inside a method and are used for processing inside the method.

Ex: public int add(int a, int b) {
private int c = 10;
return a + b + c;
}

Here c is the local variable.

Declaring Arrays:

In Java, arrays are objects that store multiple variables of the same type, or variables that are all subclasses of the same type. Arrays can hold either primitives or object references, but the array itself will always be an object on the heap, even if the array is declared to hold primitive elements. In other words, there is no such thing as a primitive array, but you can make an array of primitives.

The main thing you need to know about arrays in the exam perspective is how to create an array and how to assign values to the array elements.

Tip: Arrays are very useful and efficient but java has other utility classes like ArrayList or Vector that might be much better in performance than arrays. These collections give us easier access to its objects and also provide utility methods that might help us process these objects


Declaring an Array of Primitives

int[] keys; // Square brackets before name (recommended)
int keys []; // Square brackets after name (legal but less
// readable)

Declaring an Array of Object References

Thread[] processes; // Recommended
Thread processes []; // Legal but less readable

We can also declare multidimensional arrays, which are in fact arrays of arrays. This can be done in the following manner:

String[][] employeeNames;
String[] employeeNames[];

Above we have a 2 dimensional array which can be thought of as an array of arrays. Notice in the second example we have one square bracket before the variable name and one after. This is perfectly legal to the compiler, proving once again that just because it’s legal doesn’t mean it’s right.

Note: We will deal with assigning values to the array in a separate chapter.


Hope this chapter on Declarations was useful. I have intentionally left of declaration of Enumerations as part of this chapter because enums need to be taken up as a separate chapter because of the amount of details involved in enumerations.

Previous Chapter: Chapter 1 - Refreshing Java

Next Chapter: Chapter 3 - Declaring Enumerations (Enums)
© 2013 by www.inheritingjava.blogspot.com. All rights reserved. No part of this blog or its contents may be reproduced or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without prior written permission of the Author.

ShareThis

Google+ Followers

Followers