A recap and summary.
Declaring a variable is like declaring war or your love: you are asserting that a thing now exists.
A declaration has only two required parts: the type of the variable and the name
int n;
boolean b;
String s;
ArrayList<Integer> ns;
n
, b
, s
, and ns
are now names we can use to refer to values of the types int
, boolean
, String
, and ArrayList<Integer>
respectively.
Assigning a variable is when we give it a value.
n = 42;
b = true;
s = "hello";
ns = new ArrayList<>();
After these lines run, n
, b
, s
, and ns
all have the values given.
Initializing a variable is just a special name for the first time we assign it a value. Often we combine declaration and initialization in one step:
int n = 42;
boolean b = true;
String s = "hello";
ArrayList<Integer> ns = new ArrayList<>();
The whole point of defining a variable is to be able to use the name to refer to a value.
System.out.println(x * 10);
When we talk about code we also often use the names of variable as a stand-in for the value they name. For instance, how many times does this loop run:
for (int i = 0; i < n; i++) {...
We say “n” times meaning it will run as many times as the value of the variable n
when that line of code executes.
The scope of a variable is the part of the program in which it can be referred to.
From the point of view of scope there are two kinds of variables member variables and local variables.
public class Foo {
public static int X = 100;
public int y = 42;
}
X
and y
are both member variables. Their scope is unlimited. (I.e. they can be referred to anywhere.)
Inside the class we can use just their the name X
or y
.
Outside the class via the class name for X
and via some instance of Foo
for y
: Foo.X
or myFoo.y
.
public class Foo {
private static int X = 100;
private int y = 42;
}
Member variables can be marked private
which prevents them from being referred to outside of the body of the class in which they are defined.
Technically accessibility and scope are different things but the practical effect is the same as if their scope was limited to the class.
public class Foo {
public void bar(int y) {
int z = 100;
System.out.println(x + y * z);
}
}
y
and z
are local variables. Their scope is limited to the body of the bar
method.
Other y
and z
variables can exist elsewhere but would be different variables.
public class Foo {
public bar(int n) {
for (int i = 0; i < n; i++) {
double r = Math.random();
System.out.println(r * i);
}
}
}
n
is a local variable scoped to the body of bar
.
i
is a local variable whose scope is the body of the for
loop plus the loop header.
r
is a local variable whose scope is the body of the for
loop.
Scopes can overlap e.g. the body of a method is contained within the body of the class in which it is defined.
Thus it’s possible for variables with the same name to exist in overlapping scopes.
public class Foo {
private int x;
public Foo(int x) {
this.x = x;
}
}
The name x
names two different variables, the member variable and the parameter to the constructor.
This is a common idiom in constructors where we use this.x
to specifically refer to the shadowed member variable.
public class Digits {
private ArrayList<Integer> digitList;
public Digits(int number) {
ArrayList<Integer> digitList = new ArrayList<>();
// stuff with digitList
}
public String toString() {
return digitList.toString();
}
}
Why we we get a NullPointerException
when toString
is called?
public class Digits {
private ArrayList<Integer> digitList;
public Digits(int number) {
digitList = new ArrayList<>();
// stuff with digitList
}
public String toString() {
return digitList.toString();
}
}
Leave the declaration of the member variable.
Initialize the variable in the constructor.
public class Digits {
private ArrayList<Integer> digitList = new ArrayList<>();
public Digits(int number) {
// stuff with digitList
}
public String toString() {
return digitList.toString();
}
}
Declare and initialize the member variable in one step.
Member | Local | |
---|---|---|
Declared | At the top level of class | As parameters and within the bodies of methods and constructors |
Scope | Anywhere they are accessible | Only within nearest set of enclosing {} s or the defining construct (e.g. method body for method parameters and whole for loop for loop variables.) |
Default value if not initialized | Zero value for type: 0 , 0.0 , false , or null |
None. Must be initialized before use. |
Can be shadowed? | Yes | No
(Java is especially picky about this) |
Can be public or private ? |
Yes | No |
Can be static ? |
Yes | No |
Can be accessed via this or class name? |
Yes | No |
declaration | where we create a variable with a specific type and name |
member variable | a variable declared at the top-level of class. |
local variable | a variable declared within a method or constructor |
scope | the part of a program where a variable name is meaningful |
initialization | when we we assign a value to a variable for the first time |