I don't understand why a static method can't use non-static data. Can anybody explain what the problems are and why we can't do it?
-
11Because only static data exist from the point of view of static methods.– mouvicielSep 11, 2013 at 13:55
-
4Sharing your research helps everyone. Tell us what you've tried and why it didn’t meet your needs. This demonstrates that you’ve taken the time to try to help yourself, it saves us from reiterating obvious answers, and most of all it helps you get a more specific and relevant answer. Also see How to Ask– gnatSep 11, 2013 at 18:04
-
19@gnat in this case OP is trying to understand the reason behind a design decision. What do you expect him to try in this case?– GeekSep 11, 2013 at 18:13
-
2@Geek - the existence of static methods, static data is a language design issue. Assuming standard meanings, the fact that static methods cannot access instance data is not. The limitation is implied by the definitions and what is possible and makes sense, not by some language designers foibles.– user8709Sep 11, 2013 at 18:59
-
6To paraphrase Gertrude Stein: "There's no this there."– hippo-dancerSep 12, 2013 at 23:57
8 Answers
In most OO languages, when you define a method inside a class, it becomes an Instance Method. When you create a new instance of that class, via the new
keyword, you initialize a new set of data unique to just that instance. The methods belonging to that instance can then work with the data you defined on it.
Static Methods, by contrast, are ignorant of individual class instances. The static method is similar to a free function in C or C++. It isn't tied to a specific instantiation of the class. This is why they cannot access instance values. There's no instance to take a value from!
Static Data is similar to a static method. A value that is declared static
has no associated instance. It exists for every instance, and is only declared in a single place in memory. If it ever gets changed, it will change for every instance of that class.
A Static Method can access Static Data because they both exist independently of specific instances of a class.
It might help to look at how you invoke a static method, compared to a instance method. Let's say we had the following class (using Java-like pseudocode):
class Foo {
// This static value belongs to the class Foo
public static final string name = "Foo";
// This non-static value will be unique for every instance
private int value;
public Foo(int value) {
this.value = value;
}
public void sayValue() {
println("Instance Value: " + value);
}
public static void sayName() {
println("Static Value: " + name);
}
}
Foo foo1 = new Foo(10);
Foo foo2 = new Foo(20);
foo1.sayValue(); // Prints "Instance Value: 10" - called on foo1
foo2.sayValue(); // Prints "Instance Value: 20" - called on foo2
Foo.sayName(); // Prints "Static Value: Foo" - called on Foo (not foo1 or foo2)
Update
As COME FROM points out in the comments, a static method is capable of working with non-static data, but it must be passed explicitly. Let's assume the Foo
class had another method:
public static Foo Add(Foo foo1, Foo foo2) {
return new Foo(foo1.value + foo2.value);
}
Add
is still static, and has no value
instances of its own, but being a member of the class Foo it can access the private value
fields of the passed-in foo1
and foo2
instances. In this case, we're using it to return a new Foo
with the added values of both passed-in values.
Foo foo3 = Foo.Add(foo1, foo2); // creates a new Foo with a value of 30
-
30Expanding on "There's no instance to take a value from" - even if there are instances, the static method can't know which instance to take a value from.– user8709Sep 11, 2013 at 18:53
-
10This is a lot less complicated to explain in languages that don't force everything to be part of an object by default. Sep 13, 2013 at 0:00
-
3@Mason True words. Languages like Java kind of enforce a false notion that a function is something that necessarily belongs to a class.– KChalouxSep 13, 2013 at 12:29
-
5This is a fine answer but it still fails to tell the whole truth: static methods can access non-static data. They just don't have the implicit object or
this
-reference available. I think that is vitally important to understand. Sep 13, 2013 at 13:38 -
2@COMEFROM You mean by explicit passing? I can make a note of it, if I'm understanding you correctly. I assumed it was implied that a static method could access explicitly passed non-static data, given that any function can work on data explicitly passed to it.– KChalouxSep 13, 2013 at 15:16
Lets explain it with a hypothetical sample.
Imagine a simple class:
class User
{
User(string n) { name = n; };
string name;
}
Now we create 2 instances of this class:
User Bones = new User("Bones");
User Jim = new User("Jim");
now, think - what if we add a new static method to User, eg:
static string GetName();
and you call it:
string x = User::GetName()
what would x contain? "Jim", "Bones", or something else?
The problem is that a static method is a single method, defined on the class, not the objects. As a result, you don't know which object it might apply to. This is why its a special thing. Its best to think of static methods as individual things, like functions in C for example. That languages like Java have them contained inside classes is mainly a problem with Java not allowing anything to exist outside a class, so functions like this have to be forced inside a class in some manner (a bit like how main() is forced to be inside a class too when all sense says it should be a singular, standalone function).
Non-static data is associated to an instance of the class. Static methods (and data) are not associated to a particular instance of the class. There does not need to be an instance of a class to use static methods on it. Even if there were instance(s), there would be no way for Java to guarantee that you are operating on the instance you are expecting when you call a static method. Therefore, static methods cannot have access to non-static data.
It can use field data; consider the following java code:
class MyBean {
private String myString;
static void myStaticMethod() {
myString = "tada";/*not allowed; if this was possible how would
be different from a field without static?*/
MyBean myBean = new MyBean();//allowed if associated with an instance
myBean.myString = "tada";
}
}
-
While this may technically be a static method using non-static data, it misses the point. Of course you can create a new instance and access it. But that has nothing at all to do with
static
ness.– BobsonSep 11, 2013 at 16:17 -
2Actually, I think this is a very good addition to explaining the point. It highlights the point that the static method needs an instance of the class before it can access non-static data while providing an intuitive reason why that is so. Sep 12, 2013 at 3:23
-
-
@BenHocking "yes" even i think it is good point telling that "instance variable is always associated with object"– JAVASep 15, 2013 at 3:16
I think the issue here is one of understanding.
From a technical standpoint a static method called from within an object would be quite capable of seeing the instance fields. I strongly suspect this is what caused the question in the first place.
The issue is that methods can be called from outside the object. At that point there's no instance data to provide them--and thus no way for the compiler to resolve the code. Since allowing instance data caused a contradiction we must not allow instance data.
-
I disagree. A static method cannot access instance data because instance data must be accessed via an instance of the object and the static method is not associated with any given instance (but with the class definition).– Phill W.Feb 28, 2017 at 11:53
-
You miss my point. If it's called from within the class the compiler could pass an instance pointer like it does when it's not a static class. The problem comes if it's called from elsewhere--which means private static methods could access instance data (albeit by internally basically ignoring the static.) Feb 28, 2017 at 18:06
-
Yes, the compiler /could/ but why should it? Passing such a pointer essentially reduces it to an instance method. Your stipulation that it is only private methods that could do this is moot - Reflection technologies make /all/ methods accessible - private or not - making this an even more risky proposition. Our Friends in Redmond have gone in the other direction; their languages raise a warning if you try to call a static method against an object instance (and not the class itself).– Phill W.Mar 1, 2017 at 11:31
Think of it as static methods living in a non-object-oriented dimension.
In the "object oriented dimension" a class can spawn multiples egos (instances), each ego has conscience of itself via its state.
In the flat, non-OO-dimension a class is oblivious of their egos living in the OO-dimension. Their world is flat and procedural, almost as if OOP had not been invented yet, and as if the class was a small procedural program, and the static data were just global variables.
I think the easiest way to explain this is to look at some code and then consider what results we would expect the code to produce.
// Create three new cars. Cars have a name attribute.
Car car1 = new Car("Mazda3");
Car car2 = new Car("FordFocus");
Car car3 = new Car("HondaFit");
// Now we would like to print the names of some cars:
// First off why don't we try this:
Car.printCarName();
// Expected behaviour:
// If we think about what we are trying to do here it doesn't
// really make sense. What instance of car name should this
// print? Should it print Mazda3? FordFoucs?
// What is the expected behaviour? If we are going to have a
// static call on car call printCarName it should probably do
// something like print all car names or a random car name or
// throw an error.
//Now lets try this instead:
Car.printCarName(car1);
// Expected Behaviour:
// Luckily the expected behaviour is very clear here. This
// should print Mazda3. This works as expected.
// Finally lets try this:
car1.printMyName();
// Expected Behaviour:
// Same as previous example, however this is the *right* way
// to do it.
For completeness here is the car class:
public class Car{
public String name;
public Car(String name){
this.name = name;
}
public static printCarName(){
print "Not sure what to do here... Don't know which car you are talking about.";
}
public static printCarName(Car c){
print c.name;
}
public /*NOT static*/ printMyName(){
print this.name;
}
}
-
-
1
The other answers pretty much say it all, however, there is some "detail" I'd like to add.
Static methods (say those in Java) just don't have an implicit object associated to them (accessible through this
) whose members you can access usually directly by name.
That doesn't mean they cannot access non-static data.
class MyClass {
public static void foo(MyOtherClass object) {
System.out.println(object.member);
}
}
class MyOtherClass {
public int member = 10;
}
I know this is just a detail, but I found your question strange when I read it. "Can use only static data" is too much restrictive.
By the way, I didn't test the code, I just wrote it here in order to exemplify what I was saying.