Re: non-static context
- From: "Rhino" <no.offline.contact.please@xxxxxxxxxx>
- Date: Fri, 9 Dec 2005 19:26:34 -0500
"Jony" <kimfinale@xxxxxxxxx> wrote in message
news:1134164933.645156.111200@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Hi, I know that there are already many posts about non-static context.
> But, i don't still understand. So please bear with me. I got the
> following error message. I know if i define "deviation" as a class
> variable, then i won't get the error message.
> But I would like to understand why this happens. Would anyone explain
> about this error??
> Thank you in advance.
>
>
> non-static variable deviation cannot be referenced from a static
> context
> deviation += Math.pow((a.getWeight () - averageWeight ),
>
Okay, here's my attempt to explain this error.
Let's say that we have a trivial class, like:
----------------------------------------------------------------------------------------------------
public class MyStatic {
public static void main(String[] args) {
MyStatic myStatic = new MyStatic(10, 20);
System.out.println("Back in main()....");
}
public MyStatic(int length, int width) {
int area = length * width;
System.out.println("Area from MyStatic() = " + area);
}
}
----------------------------------------------------------------------------------------------------
The example above calculates a geometric area where area is the product of
length and width. The main method is the first method executed when we run
this application; this is the convention for all Java applications. The main
method creates a new object, myStatic, which is an instance of the class
MyStatic (note the difference in spelling of the two words: myStatic, which
starts with a lowercase letter, is an instance, while MyStatic, which starts
with an uppercase letter, is a class.)
The other method in the MyStatic class is the MyStatic method. The MyStatic
method is the first (and, in this case, only) method to be executed after
the main method itself. It is a special kind of method called a constructor
and does what the name suggests: it constructs an instance of the MyStatic
class.
Within the MyStatic constructor method, a local variable named area is
defined as an int and given a value that is the product of the two ints that
are passed into the constructor, namely length and width. Then, the
System.out.println() method displays the value of the area.
This program will compile fine - there may be a warning or two but they need
not concern us for this discussion - and, when executed, will display this:
Area from MyStatic() = 200
In this version of the MyStatic class, the area variable is _not_ static.
If you were to add the following line to the main class, after the
'System.out.println("Back in main()....");' line:
System.out.println("Area from main() = " + area);
you'd find that the program no longer compiled; you'd get the message: "area
cannot be resolved". The reason for this is that the 'area' variable is only
visible within the MyStatic constructor method. Therefore, its value can't
be displayed by 'System.out.println("Area from main() = " + area);' line.
Now, let's look at a different way of writing class MyStatic:
----------------------------------------------------------------------------------------------------
public class MyStatic {
int area = 0;
public static void main(String[] args) {
MyStatic myStatic = new MyStatic(10, 20);
System.out.println("Back in main()...");
System.out.println("Area from main() = " + area);
}
public MyStatic(int length, int width) {
int area = length * width;
System.out.println("Area from MyStatic() = " + area);
}
}
----------------------------------------------------------------------------------------------------
This version of class MyStatic won't compile. It's the same as the first
version of the class, with one addition: a class variable named area has
been defined; it's the first line within the class and is situated _before_
the main() method. The compile error occurs on the 'System.out.println("Area
from main() = " + area);' line and says: "Cannot make a static reference to
the non-static field area".
Now, let me assure you that the message is referring to the new area
variable, the one before the main() method, _not_ the area variable that is
in the MyStatic constructor method.
The problem is that our new area variable is not static. A static method
like main() can only see class variables that are also static. That's why we
get the compile error: the old area variable isn't visible to the main()
method because it is local to the MyStatic() constructor method and the new
area variable isn't visible to the main() method because it isn't static.
The solution to the compile error is to make the new area variable static so
that its definition is:
static int area = 0;
(The initialization value isn't important here and could be a different
value or even be omitted entirely; this might cause a new compiler warning
or error due to an uninitialized variable. Rather than cause extra confusion
with that side issue, I've simply set the new area variable to zero.)
Now the program should compile successfully.
If we execute the modified program, we should get this output:
Area from MyStatic() = 200
Back in main()...
Area from main() = 0
Why does the output display two different values for area? Simple: there are
two variables named area and they have two different values!!
The first line of output reports the value of the old area variable, the one
defined with the MyStatic() constructor method. It is defined as the product
of length and width and, since 10 times 20 is 200, it is no surprise that
this area variable has a value of 200. The third line of output reports that
area is 0. That is because the third line is reporting the value of the
_new_ area variable, which is static and set to 0. Not surprisingly, it
continues to have a value of 0 when we display its contents.
Having two variables named area has an obvious potential to cause confusion.
Unless we are fairly familiar with Java, it would be non-obvious to us what
value area should have at any given time. As we can see, Java does not
prevent us from having two variables named area.
So, let's consider one other version of this class:
----------------------------------------------------------------------------------------------------
public class MyStatic {
static int area = 0;
public static void main(String[] args) {
MyStatic myStatic = new MyStatic(10, 20);
System.out.println("Back in main()...");
System.out.println("Area from main() = " + area);
}
public MyStatic(int length, int width) {
area = length * width;
System.out.println("Area from MyStatic() = " + area);
}
}
----------------------------------------------------------------------------------------------------
This version looks very similar to the second version (after we put the
'static' modifier in front of the area class variable). However, there is
one very important difference: this version contains only _one_ area
variable. If you look at the MyStatic() constructor method, you'll see that
this method is very slightly different from the previous versions of the
method: the definition of area is missing the int datatype before the
variable name. This small change makes a big difference! Now, the 'area =
length * width;' line is _not_ creating a local variable called area: it is
_using_ an +_existing_ class variable named area, the one that is defined
before the main() method. So, we've gone from two area variables to a single
one, and that variable is a class variable now. Contrast that to the first
version of the program where we also had a single variable named area but
that version of area was a local variable within the MyStatic() constructor
class and was not visible in the main() method, or any other method of this
class for that matter.
Let's see what output we get when we run the third version of the class:
Area from MyStatic() = 200
Back in main...
Area from main() = 200
Hurrah! The values are now consistent!
That's not surprising, of course, since there is only one area variable now.
That variable is initialized to 0 when the program begins and is then set to
200 when the product of 10 times 20 is calculated during the execution of
the MyStatic() constructor method. The value of 200 persists back into the
main() method and until the program ends at the end of the main() method.
Let me stress that I do not mean to imply that the third version of the
class is correct and the earlier ones were wrong. The fact of the matter is
that any of the three versions might be appropriate depending on what you
are trying to do, although you would most likely choose the first or third
versions rather than risking the confusion of the second version. But the
first version is neither better nor worse than the third version; they are
just different.
Looking back on what I've just written, I really don't know if it explains
the idea clearly or just makes it more confusing. If my explanation doesn't
help you understand the issue better, simply ignore it. Someone will
probably come along and give you a clearer explanation; if they don't, seek
one out yourself! There are several Java tutorials and books, all of which
should have some discussion of static vs. non-static variables.
Rhino
.
- Follow-Ups:
- Re: non-static context
- From: Jony
- Re: non-static context
- References:
- non-static context
- From: Jony
- non-static context
- Prev by Date: Re: [OT] Re: need help on this problem.
- Next by Date: Re: Creating Integer object from int
- Previous by thread: Re: non-static context
- Next by thread: Re: non-static context
- Index(es):
Relevant Pages
|