I heard that static methods should use only static variables in java. But, main method is also static, right?
A static method is called on a class instance and not to an object of a class. This means, that a static method is not able to access instance variables, because they are only instantiated in an object.
If you want to access with a static method an instance variable, you have to declare that variable as static.
public class Test {
private static int value = 0;
public static void main(String[] args) {
value++;
}
}
But to be honest, it's not the best idea to write everything in static methods. It's better to use the main method to instantiate new objects.
Yes static method cannot call non-static methods or variables of the class directly.
EDIT : One can create any local variables.
First of all, a technicality: it's NOT true that "main
method is also static". You can define a non-static main
method, with whatever signature you choose; it just won't be a valid Java application entry point.
With regards to "static methods should use only static variables", this is also NOT true. The key concept here is that static methods and fields are class-specific, not instance-specific. You simply can't access an instance variable/method if you don't actually have an instance of that class; it's a compilation error.
So to be precise, without an instance, you can't access instance fields/methods. You can access static fields/methods without an instance. If you need to access instance fields/methods from a static method, you have to get an instance of that class one way or another, either by simply instantiating it, or by getting a reference to it from a static field or method parameter.
Let's take a look at this simple example:
public static void main(String args[]) {
System.out.println(args.length);
}
length
is NOT a static field; it's an instance field of array instances, which args
is. The static method main
is able to get this instance (and thus access its instance methods and fields) because it's passed in as an argument.
Also, println
is NOT a static method; it's an instance method of PrintStream
instances. The static method main
is able to get this instance by accessing the static field out
of the class System
.
To summarize:
- A Java application entry point is a method that:
- is named
main
- is
public
andstatic
- returns
void
and takes aString[]
argument as parameter
- is named
- A method named
main
doesn't have to be a Java application entry point- (but it's best to reserve this name for that purpose)
Furthermore,
- Instance fields/methods can only be accessed through an instance
- Static fields/methods can be accessed without an instance
- Static methods can get an instance of a class by one of the following ways:
- creating a
new
instance - having it passed as an argument
- accessing it through a
static
field of a class - accepting it as the return value of a
static
method of a class - catching it as a thrown
Throwable
- creating a
Your question: is the statement " static methods should use only static variables" correct?
No. The statement is not correct.
The correct statement will be "static methods can only use those instance variables that are defined static"
Take a look at following code and read the comments:
Class A{
int i;
static int j;
public static void methodA(){
i = 5; //cannot use since i is not static
j = 2; //can use.
int k = 3; //k is local variable and can be used no problem
**EDIT:**//if you want to access i
A a = new A();
A.i = 5; //can use.
}
}
To access non-static fields (instance variables) you need to have an instance.
Inside a non-static method, this
is used as default instance:
class AnyClass {
private String nonStaticField = "Non static";
void nonStaticMethod() {
this.nonStaticField = "a text"; // accessing field of this
nonStaticField = "a text"; // same as before
}
}
Inside a static method there is no this
to use as default instance, but you can1 still access instance variables if you provide the instance:
class AnyClass {
private String nonStaticField = "Non static";
static void staticMethod() {
AnyClass example = new AnyClass();
example.nonStaticField = "new value for non-static field";
}
}
1 - the field must also be accessible by Java's access control (declared public
or in the same class ...)
Maybe this piece of code will enlighten you:
public class Main {
private String instanceField = "Joe";
private void instanceMethod() {
System.out.println("Instance name=" + instanceField);
}
public static void main(String[] args) {
// cannot change instance field without an instance
instanceField = "Indy"; // compilation error
// cannot call an instance method without an instance
instanceMethod(); // compilation error
// create an instance
Main instance = new Main();
// change instance field
instance.instanceField = "Sydney";
// call instance method
instance.instanceMethod();
}
}
So you cannot access instance members without an instance. Within the context of a static method you don't have a reference to an instance unless you receive or create one.
Hope this helps.