Friday, November 13, 2009

SCJP 1.6 Study Guide: Declarations and Access Controls Part 8

Variable Declaration

When we need to manipulate values provided by the users of our application we can temporarily store them in variables. But to be able to assign values to variables you need to declare themfirst. And when you declare a variable you need to define what type of values that variable can hold and the variable name.

Example:
public class Person{
int age; // instance variable declaration
// where int means it can only store int values
String name;
}
Primitive and Reference Variable. We can categorize the age variable of class Person as a primitive variable. Primitive variables can be one of 8 types: char, boolean, byte, short, int, long, float or double. How about the name variable? It was declared to store values of type String. Whenever a variable is declared to be a type of something other than the primitive types then it's called a reference variable. A reference variable can be used to refer to an object of the declared type or a subtype of the declared type through polymorphism which we will discuss in the next section.

Declaring Primitive Variables. Primitive variables can be declared as instance variables, class variables(static variables), method parameters or local variables. We will only focus on declaring variables and discuss the several ways of assigning values to them on a later post.

Example:
public class Student{
private int yearLevel, age;
public static final int TOTAL_NO_OF_YEARS = 4;

public void setAge(int age){
this.age = age;
}

public int getRemainingYears(){
int remainingYears = TOTAL_NO_OF_YEARS - yearLevel;
return remainingYears;
}
}
The example above declares primitive variables as instance variable(yearLevel and age), class variable(TOTAL_NO_OF_YEARS), local variable(remainingYears) and method parameter(age). Another thing to learn from the example is that you can declare several primitive variables of the same type on one line(like yearLevel and age), just separate them with comma.
TypeBitsRange
byte8-27 to 27-1
short16-215 to 215-1
int32-231 to 231-1
long64-263 to 263-1
float32n/a
double64n/a

The table above shows the range of the six primitive number types. Determining the range of floating point numbers is very complicated, fortunately we don't need to know them for the exam.

Variables of the boolean type can only be true or false.

The char type may contain a 16-bit Unicode character. The char variable is really an unsigned 16-bit integer type(0-65535) and can be assigned to any number type large enough to hold 65535.

Declaring Reference Variables. Like primitive variables, reference variables can be declared as instance variables, class variables, method parameters or local variables.

Example:
public class Student{
private String firstName, lastName;
public static final String SCHOOL_NAME = "My School";

public void setFirstName(String firstName){
this.firstName = firstName;
}

public void getFullName(){
String fullName = firstName + " " + lastName;
return fullName;
}
}
Let's discuss the differences of instance variable, static variable, local variable and method parameter.

Instance Variables. Instance variables are variables declared inside a class but outside of any methods. When you don't give initial values to instance variables they will be given default values depending on their type.
TypeDefault Value

byte0
short0
int0
long0L
float0.0F
double0.0
char'\u0000'
booleanfalse
Stringnull
Other Objectsnull

These are the list of modifiers which can be used in declaring instance variables:
  • Any of the four access levels (three access modifiers: public, private and protected)
  • final
  • transient
  • static (but this variable is already a class variable or a static variable not an instance variable)
We'll discuss more on the difference of an instance member(non-static variable and method) and a class member(static variable and method).

Local Variables. Local variables are variables declared inside a method.

Example:
public class Student{
String firstName, lastName;

public void setFirstName(String firstName){ // firstName parameter is
this.firstName = firstName; // also a local variable
}

public void getFullName(){
String fullName = firstName + " " + lastName; // fullName is a local variable
return fullName;
}
}
Method parameters are also considered as local variables since they are declared in the method declaration.

A local variable lives when declared inside a method and dies when the method has completed. Basically it is already non-accessible outside the method. The following code will not compile.

Example:
public class Student{
String firstName, lastName;

public void getFullName(){
String fullName = firstName + " " + lastName; // fullName is a local variable
return fullName;
}

public String toString(){
return fullName; // compile error fullName is not declared
// inside toString() but inside getFullName()
}
}
Unlike instance variables which can have default values, local variables needs to be initialized before it is used by any statement. Usually you give a local variable a value on the same line where you declare it. However, you can initialize a local variable on a different line just as long as it is not used first.

Example:
public class Student{
String firstName, lastName;

public void getFullName(){
String fullName = firstName + " " + lastName; // fullName is initialized
return fullName;
}

public String toString(){
String fullName; // fullName is declared but not initialized
return fullName; // compile error
}
}
Local variables can only be marked with the final modifier.

Shadowing. Shadowing happens when you try to declare a local variable with the same name as an instance variable. You usually do this in naming method parameters to achieve readability. The following code is an example but will cause what we call naming collision. It will still compile but should not be followed.

Example:
public class Student{
String firstName, lastName;

public void setFirstName(String firstName){
firstName = firstName; // naming collision
}
}
To resolve naming collision the this keyword is used to refer to the current active object. Question: Which firstName is being referred by the two firstName variables inside setFirstName()?

Example:
public class Student{
String firstName, lastName;

public void setFirstName(String firstName){
this.firstName = firstName; // firstName on the left refers
// to the instance variable firstName
// since we used the this keyword
}
}
Final Variables. When a variable is declared with the final keyword you are not allowed to reassign a value to that variable. For primitive variables this means that you cannot alter it's initial value.

Example:
public class Student{
private static final String SCHOOL_NAME = "My School";

public static String getSchoolName(){
SCHOOL_NAME = "Your School"; // compile error can't reassign value
// to final a variable
return SCHOOL_NAME;
}
}
For a reference variable it means you cannot assign it to another object but you still can modify the state (values of the instance variables of the object it refers to). There are no final objects just final references. We'll discuss more on this on a later post but here's a quick look:

Example:
public class Student{
String firstName, lastName;

public void setFirstName(String firstName){
this.firstName = firstName;
}
}
public class TestStudent{
public static void main(String[] args){
final Student student = new Student();
student.setFirstName("Bob"); // OK to modify firstName

Student stud = new Student();
student = stud; // compile error
}
}
Transient Variables. When you mark a variable with the transient keyword you're telling the JVM to skip that variable when you attempt to serialize the object containing it. Simply put serialization allows you to save an object to a file or send it through a network. We'll discuss serialization on later posts. The transient keyword can only be used with instance variables.

Volatile Variables. When a variable is declared with the volatile modifier it tells the JVM that a thread accessing that variable must always reconcile(check) its own private copy with the master copy. You don't really need to know more about the volatile keyword except that like the transient keyword it can only be used with instance variables.

Static Variables and Methods. Static variables and methods are variables and methods marked with the static keyword. They are usually called class members.

Class members exist independent of any instance of the class they are declared in. They are created first before any creation of object of that class. There will be only one copy of each class members regardless of the number of instances of that class.

The following can be declared as static:
  • methods
  • variables except local variables
  • nested class (except classes declared inside a method)
  • initialization blocks
This post is definitely a long one. I suggest to read it a second time and try to code if something is not clear to you. Static variables and methods will be discussed deeper on later posts. The next post will discuss on declaring arrays and enums and it will be the last part for the Declarations and Access Controls section.

0 comments:

Post a Comment