In Java, the terms instance and object mean (very close to) the same thing. See the Primitive types vs references exercises for practice constructing and using instances (objects).
Static is the opposite of instance. Variables and methods can be declared as static
. A method that is declared without the static
modifier is an instance method. A variable declared outside a method without the static
modifier is an instance variable.
Parameters are declared within a method header. Parameters are neither static nor instance. Local variables are declared within a method. Local variables are neither static nor instance.
Static vs instance in client code
Static methods & fields
System.out.println(Math.pow(2, 8)); // prints 256.0
System.out.println(Math.sqrt(4.0)); // prints 2.0
System.out.println(Math.PI); // prints 3.141592653589793
The Math
class contains static methods, including pow
and sqrt
. A static method runs directly on a class, not on a specific instance (object) of a class.
Methods that do not require access to state (values of instance variables) are often declared as static
.
The Math
class also contains public static final
fields, including PI
. The static
and final
modifiers are often confused. The final
modifier prevents the value of a field from being changed after it has been set. The static
modifier attaches the field to the class rather than to an instance (object) of the class.
Instance methods
String firstName = "Brandon";
String lastName = "Horn";
System.out.println(firstName.indexOf("o")); // prints 5
System.out.println(lastName.indexOf("o")); // prints 1
System.out.println(String.indexOf("o")); // compile time error
indexOf
is an instance method of the String
class. It runs on a specific instance (object) of type String
.
Methods that require access to state must not be declared as static
.
The first and second calls to indexOf("o")
return different results because they are run on different instances (objects). The String
object "Brandon"
contains "o"
at index 5
. The String
object "Horn"
contains "o"
at index 1
.
The third call to indexOf("o")
causes a compile time error. indexOf
is an instance method, not a static method. It must be run on a specific instance (object) of type String
, not directly on the String
class.
Static vs instance inside a class
Instance variables exist inside a specific instance (object) of a class. Each object (instance) of a class gets its own copies of that class’s instance variables.
Instance methods run on a specific instance (object) of a class. The Primitive types vs references exercises demonstrate the use of instance variables by instance methods.
Static variables exist as part of a class. Exactly one copy of each static variable exists regardless of whether zero, one, or more objects of that class have been created.
Correct example with Student
class
public class Student
{
private static String schoolCode;
private int studentNumber;
public Student(int stuNum)
{
studentNumber = stuNum;
}
public int getStudentNumber()
{
return studentNumber;
}
public String getStudentID()
{
return schoolCode + "-" + studentNumber;
}
public static String getSchoolCode()
{
return schoolCode;
}
public static void setSchoolCode(String schCode)
{
schoolCode = schCode;
}
}
public class StudentRunner
{
public static void main(String[] args)
{
Student.setSchoolCode("MHHS");
Student s1 = new Student(567);
Student s2 = new Student(678);
System.out.println(s1.getStudentID());
System.out.println(s2.getStudentID());
System.out.println(Student.getSchoolCode());
}
}
The diagram above shows the memory state after the first 3 lines of the main
method (and throughout the rest of the method).
All students share the same school ID, which is stored in the static variable schoolCode
. Each student has a unique student number, which is stored in the instance variable studentNumber
.
A student ID is created by concatenating the school code, a dash (-
), and the student number. In the example above, s1.getStudentID()
returns "MHHS-567"
and s2.getStudentID()
returns "MHHS-678"
.
getStudentID
is (and must be) an instance method of Student
. getStudentID
accesses the static variable schoolCode
and the instance variable studentNumber
. Instance methods can access both static and instance variables.
The code in the main
method prints:
MHHS-567
MHHS-678
MHHS
Incorrect example with static getStudentID
method
public class Student
{
// static modifier added to getStudentID
public static String getStudentID()
{
return schoolCode + "-" + studentNumber;
}
// All other code in Student remains unchanged.
}
Consider the above modification to the Student
class.
The getStudentID
method has been incorrectly declared as static
. Static methods cannot access instance variables. The attempt to access the instance variable studentNumber
results in a compile time error.
A static method is run on a class, not on a specific instance (object) of a class. Since there is no instance, there are no instance variables to access.
In this (incorrect) example, the method would be called as:
System.out.println(Student.getStudentID());
This is equivalent to asking for the student ID of the Student
class, rather than of a specific student. The request doesn’t make sense.
Incorrect example with static studentNumber
field
public class Student
{
// static modifier added to studentNumber
private static int studentNumber;
// All other code in Student remains unchanged.
}
Consider the above modification to the Student
class.
The studentNumber
field has been incorrectly declared as static
. Static fields exist once per class, not once per instance of a class.
The original StudentRunner main
method has been copied below.
public static void main(String[] args)
{
Student.setSchoolCode("MHHS");
Student s1 = new Student(567);
Student s2 = new Student(678);
System.out.println(s1.getStudentID());
System.out.println(s2.getStudentID());
System.out.println(Student.getSchoolCode());
}
The diagram above shows the memory state after construction of the second Student
object (with the studentNumber
field incorrectly declared as static
). As a static variable, studentNumber
exists once, not once per object.
The code in the main
method prints:
MHHS-678
MHHS-678
MHHS
Incorrect example that appears correct
public static void main(String[] args)
{
Student.setSchoolCode("MHHS");
Student s1 = new Student(567);
System.out.println(s1.getStudentID()); // moved here
Student s2 = new Student(678);
System.out.println(s2.getStudentID());
System.out.println(Student.getSchoolCode());
}
The code above is a modified version of the StudentRunner main
method. The code to print s1.getStudentID()
has been moved immediately after the construction of the first Student
object.
Even with the Student
variable studentNumber
incorrectly declared as static
, the code above correctly prints:
MHHS-567
MHHS-678
MHHS
Each time the Student
constructor runs, it sets the value of the static variable studentNumber
. The value of the variable is correct each time getStudentID()
is run. This does not mean the Student
class is correct.
If the line:
System.out.println(s1.getStudentID());
is added to the end of the main
method, it will incorrectly print:
MHHS-678
Help & comments
Get help from AP CS Tutor Brandon Horn