In general, something defined as static
just means that a class instance (object) is not required to access it.
Since it is "static", it only exists in one form, as opposed to being "dynamic", where it may be different depending on the instance.
A static
variable is defined at the class level (outside of any methods) and can be accessed by other classes without instantiating the class.
E.g. x = ClassName.staticVariableName;
(assuming that the variable is not private).
But remember, a static variable can be accessed from an instance; it is just unneccesary.
E.g. x = ClassInstance.staticVariableName;
or x = new ClassName(args).staticVariableName;
.
It may be called a class variable or a field. It is called a class variable because the variable belongs to the class as a whole, not any specific instance of the class. All instances have this variable in common, and so this variable may be referenced from the class without an instance of it (object).
For example, you may want to keep track of the number of instances created. So if you had the class Student
, you can have a class variable called numberOfStudents
.
An non-static
variable is defined at the class level (outside of any methods), but requires a class instance to be accessed.
E.g. x = ClassInstance.instanceVariableName;
or x = new ClassName(args).instanceVariableName;
(assuming that the variable is not private).
It is called an instance variable because it is specific to the instance created.
For example, let's say you had a class called Student
and so every
class instance (object) was a new student. The name of each student would be stored as an instance variable, since the name is specific to every instance (every student).
Look at an example of the complete picture:
public class Student { public String name = ""; // instance variable public static int numberOfStudents = 0; // class variable or field // constructor method public Student (String name) { this.name = name; this.numberOfStudents++; } } public class TestClass { public void testMethod() { Student student1 = new Student("Foo"); // accessing static variable System.out.println(Student.numberOfStudents); // prints "1" System.out.println(student1.numberOfStudents); // prints "1" Student student2 = new Student("Bar"); // accessing static variable System.out.println(Student.numberOfStudents); // prints "2" System.out.println(student2.numberOfStudents); // prints "2" // accessing instance variable System.out.println(Student.name); // doesn't work - what would the value be?! System.out.println(student1.name); // prints "Foo" System.out.println(student2.name); // prints "Bar" } }
Constants (declared as final
), such as public static final TAX_RATE = 0.13;
, are often static
because they may be constant, relative of context. In the TAX_RATE
example, the tax rate may be the same regardless of the instance created. For example, if the objects were items, the tax could be the same for all items. However, if the objects were countries, the tax rate may vary. Therefore, the TAX_RATE
variable should not be declared static
in that case.
A static
method is a method that can be accessed from any class without a class instance. However, it can be accessed from an instance, but is not necessary.
E.g. ClassName.staticMethod(); // correct approach
or ClassInstance.staticMethod(); // calling from instance
or new ClassName.staticMethod(); // calling from instance
This type of method is called a class method since it is a member of the class as a whole, not any specific instance of it. The method does not perform a task related to any specific instance. The method is called from the general class.
For example, let's say we have the class Height
. And let's say we have a method that converts inches into centimeters (heights for different number systems) called convertInToCm(double)
. Is that method related to any specific Height
object? Or is it only relative to the class in general? The answer is the latter, so the method can be defined as a class method (static
).
A non-static
method is a method that requires a class instance to be accessed.
E.g. ClassInstance.instanceMethod();
or new ClassName.instanceMethod();
This type of method is called an instance method since the method is specific to the instance created.
For example, if a Height
object was created and we wanted to call a method that returns the height of that object, is the method a class or instance method? It's an instance method, since the height is specific to that instance. Getter and setter methods are typically instance methods, since they typically return a value related to that specific object created.
Look at an example of the complete picture:
public class Height { private double height = 0.0; // instance variable: height of object in centimeters private static final double INCH_TO_CM_RATIO = 2.54; // class constant variable that represents the ratio of 1 inch to 1 centimeter // constructor method public Height(double height) { this.height = height; } // getter method public double getHeight() { return this.height; } // class method for height conversion public static double convertInToCm(double inches) { return inches * INCH_TO_CM_RATIO; } } public class TestClass { public void testMethod() { Height height1 = new Height(185.42); // creates Height object of 185.42 cm double heightInInches = 73; // 73 inches double heightInCm = Height.convertInToCm(heightInInches); // returns 73 inches to the cm equivalent (185.42 cm) Height height2 = new Height(heightInCm); // creates Height object of 73 inches or 185.42 cm Height height3 = new Height(Height.convertInToCm(73)); // the same as height2 } }
Keep in mind that non-static references (instance variables, instance methods and class instances) cannot be made from a static method. This is because a static method can be accessed WITHOUT any instance created. So if you reference methods or variables that require an instance, what would happen?
Look at the following example of how that could go wrong:
public class MyClass { private String name = ""; // instance variable // constructor method public MyClass (String name) { this.name = name; } // getter method for name (instance method) public String getName() { return this.name; } public static void staticMethod() { System.out.println(getName()); // ERROR. Can't call instance method from class method. } } public class TestClass { public void testMethod() { MyClass.staticMethod(); // What would be printed? By default, the name is "". // No name is set until an instance is created (constructor method)! } }
You can only declare a nested class as static
, since declaring an entire class as static would be useless.
An inner class is a non-static nested class (as opposed to a static nested class).
The difference between an inner class and a static nested class is that a static nested class can have its methods accessed without instantiating the static nested class. An inner class must be instantiated to access its methods, and therefore the outer class must be instantiated as well.
Look at the following example for use of static
vs non-static
nested classes:
public class OuterClass { public OuterClass(int i) { } public static class StaticNestedClass { public void instanceMethod() { } public static void staticMethod() { } } public class InnerClass { } } public class TestClass { public void testMethod() { // Use of a static nested class: // Instantiate the static nested class: // access the static nested class WITHOUT instantiating the static nested class OuterClass.StaticNestedClass staticNestedClass = new OuterClass.StaticNestedClass(); // works // Use the methods inside the static nested class: staticNestedClass.staticMethod(); // works staticNestedClass.instanceMethod(); // works // (instantiate the outer class to have access to the instance method inside the static nested class) new OuterClass.StaticNestedClass().instanceMethod(); // works // access the STATIC method inside the static nested class WITHOUT any instantiating OuterClass.StaticNestedClass.staticMethod(); // works // access the INSTANCE method inside the static nested class WITHOUT any instantiating //OuterClass.StaticNestedClass.instanceMethod(); // doesn't work // access the INSTANCE method inside the static nested class WITH instantiating the outer class new OuterClass.StaticNestedClass().instanceMethod(); // works // Use of an inner class: // Instantiate the inner class: // access the inner class WITHOUT instantiating the inner class OuterClass.InnerClass innerClass = new OuterClass.InnerClass(); // doesn't work // access the inner class WITH instantiating the inner class OuterClass.InnerClass innerClass2 = new OuterClass(5).new InnerClass(); // works } }
Created: June 1, 2015
Completed in full by: Michael Yaworski