Describe how variables are declared and assigned objects.
Declaring variables in Java
Variable declarations associate a type with a variable name (identifier).
They also (optionally) initialize the variable to a value of its type. Variables of a primitive type store values of their type. Variables of an object type store references to objects of their type.
Variables of primitive types and object types
Java field Variable
A field variable[1], also referred to as a field[2] or a member variable[3], is a variable that is declared as a member of a class. It stores state information about the class (static variables) or about instances of the class (non-static) variables.
A local variable is a variable that is declared and used within a method.
Field or member variable versus a local variable in a method
The following variable declarations are legal in Java.
package com.java.basics;
public class VariableInitialization {
public static void main(String[] args) {
int a, b, c;
a = b = c = 100;
int f, g, h = 100;
int x = 100, y, z;
}
}
In Java, field variables (also known as fields, instance variables, or member variables) are variables declared within a class but outside any method, constructor, or block. They represent the state or attributes of an object created from the class and are stored in the object's memory for as long as the object exists.
Key Characteristics of Field Variables:
Scope: They belong to an instance of the class (object) or, if declared static, to the class itself.
Declaration: Defined directly inside the class body, typically at the top.
Default Values: If not initialized, field variables are automatically assigned default values (e.g., 0 for int, null for objects, false for boolean).
Access: Can have access modifiers like public, private, protected, or default (package-private).
Lifetime: Instance field variables exist as long as the object exists; static field variables exist for the lifetime of the program.
Example:
public class Car {
// Instance field variables
private String model;
private int year;
// Static field variable
public static int totalCars = 0;
public Car(String model, int year) {
this.model = model;
this.year = year;
totalCars++; // Increment static field
}
// Method to access field variables
public String getModel() {
return model;
}
}
Explanation:
model and year are instance field variables, unique to each Car object.
totalCars is a static field variable, shared across all Car instances.
Field variables can be accessed and modified by methods, constructors, or directly (if allowed by access modifiers).
Note:
Field variables differ from local variables (declared inside methods or blocks), which have a limited scope and lifetime.
Use proper encapsulation (e.g., private fields with getters/setters) to control access to field variables.
The following syntax is used to declare a field variable:
modifiers type variableName initializer;
Variables may be declared using the modifiers
final,
private,
protected,
public,
static,
transient, and
volatile
These modifiers are covered later in this module. The variable's type may be a primitive type, class name, interface name, or array type.
The optional initializer consists of an equals sign followed by an expression that evaluates to a value of the variable's type.
Arrays may be initialized using a special array initialization expression that you'll learn about in the next lesson.
Local variables
Local variables are declared in the same way as field variables except that local variables may only use the final modifier.
The final modifier (refer to Module 3) identifies that a local variable may be accessed by an inner class once the variable
has been assigned a value. Final local variables may not be modified once they have been initialized.
Atomic variables
Click on the link below to read about the Atomic variables and classes that support lock-free thread-safe programming on single variables.
Atomic Variables in the java.util.concurrent.atomic package
Java provides atomic variables. Here is a list of some of the classes in this package and their short description:
1. AtomicBoolean:
Atomically updatable Boolean value.
2. AtomicInteger:
Atomically updatable int value; inherits from the Number class.
3. AtomicIntegerArray:
An int array in which elements can be updated atomically.
4. AtomicLong:
Atomically updatable long value; inherits from Number class.
5. AtomicLongArray:
A long array in which elements can be updated atomically.
6. AtomicReference < V>:
An atomically updatable object reference of type V.
7 AtomicReferenceArray < E> :
An atomically updatable array that can hold object references of type E (E refers to be base type of elements).
Atomic variables
The java.util.concurrent.atomic package defines multiple classes that support atomic operations of read-compare/modify-write on single variables. At the surface, these operations might seem similar to the operations with volatile variables. Though modifications to a volatile variable are guaranteed to be visible to other threads, volatile variables cannot define a sequence of operations (like read-compare/modify-write) as an atomic operation. Here is an example of class Book to show you how nonatomic operations with primitive variables can lead to thread interference:
class Book{
String title;
int copiesSold = 0;
Book(String title) {
this.title = title;
}
public void newSale() { // line 1
++copiesSold;
}
public void returnBook() { // line 2
--copiesSold;
}
}
Lines 1 and 2 above: Nonatomic statements include loading of variable values from memory to registers, manipulating values, and loading them back to memory. The code defined at lines 1 and 2 above is not atomic. Incrementing or decrementing primitive values includes multiple steps. When executed by multiple concurrent threads, newSale() and returnBook() can result in thread interference.
To get around this, you can define these methods as synchronized methods, but it will block thread execution. Java defines multiple convenient classes in the java.util.concurrent.atomic package that define frequently used operations like read-modify-write as atomic operations. Let us use one of these classes, AtomicInteger, in class Book, and replace the type of its primitive int variable copiesSold:
class Book{
String title;
AtomicInteger copiesSold = new AtomicInteger(0);
Book(String title) {
this.title = title;
}
public void newSale() {
copiesSold.incrementAndGet();
}
public void returnBook() {
copiesSold.decrementAndGet();
}
}
[1]Field variable: A variable that is a member of a class.