问题
I have a class Car
which has a class scope variable cost, i understand that this is a bad idea in practice, just trying to understand the effects of public scope class variables.
Will cost be accessible and modifiable by all objects of class Car, references by Car.cost, throughout all class loaders, or should i be aware of circumstances where multiple copies of Car.cost
might exist? Will there be just one Car.cost
in any given circumstance?
public class Car{
public static int cost;
public Car(int cost){
cost = cost;
}
}
public static void main(String args[]){
Car car = new Car(2);
}
回答1:
By specifying the cost
field as static
you are saying that there will only ever be a single, shared instance of that variable regardless of how many Car classes are created (within a process.) And yes, any of those instances will be able to modify that single, shared field and since you made it public, so will any other client code that has access to the Car
class. (Other processes that might use the same classes will have their own copies of static class members and will not be able to "see" across the process boundaries.)
Semantically speaking, and if I infer the meaning for Car and cost correctly, you do not want to use a static UNLESS you want ALL your cars to cost the same. In the real world cost of a car is a highly variable attribute even between the same model of the same make of a car due to trim, options etc.
回答2:
There will be only one instance of the static cost
variable per loaded class. Note however, that depending on the classloaders a class might be loaded multiple times.
As a sidenote, this won't do what you think:
public Car(int cost)
{
cost = cost;
}
Here you assign the parameter to itself (if you make it final you should get a compiler error), not the parameter to the static variable. This is called shadowing and bad practice too.
回答3:
The local scope cost (the parameter) in the Constructor hides the Class scope cost (the static). Change the constructor to be this:
public Car(int cost)
{
Car.cost = cost;
}
Do not address the class scope variable (the static cost) with this.cost
. Instead address it statically using the Class name.
Edit: Here is a simple demonstration:
public final class CostTest
{
private static int cost;
public static void main(String[] args)
{
CostTest costTest;
System.out.print("initial static cost value: ");
System.out.println(CostTest.cost);
costTest = new CostTest(17);
System.out.print("static cost value: ");
System.out.println(CostTest.cost);
System.out.print("static cost value via instance variable: ");
System.out.println(costTest.cost);
}
public CostTest(int cost)
{
CostTest.cost = cost;
}
}
When you put this in ecliipse, you should see a warning on the line System.out.println(costTest.cost);
that says something like "The static field CostTest.cost should be accessed in a static way".
回答4:
The only wrinkle here is if there are multiple ClassLoaders
involved. In this case there can be an instance of the given class within the context of each ClassLoader
which would then have a separate set of static fields associated with it. Most, if not all, Servlet & J2EE containers use multiple ClassLoaders
, typically one per web-app.
The ClassLoaders
are typically hierarchical, such that you can access classes loaded from a parent ClassLoader
. In this way, if you really need a global singleton across multiple web-apps, you generally try to have your singleton loaded in a root ClassLoader
so that it can be accessed everywhere.
Check out this description for an example: http://vanillajava.blogspot.com/2011/07/java-secret-loading-and-unloading.html
回答5:
Multiple Car.cost variable here CANNOT exist, because Car.cost is accesible from every class in loaded in the classpath (because it's public and static in the same time).
When something is 'public static' in the OO languages this means that it can be viewed as a global variable in the procedure languages. It's almost the same.
So, for conclusion, the instance of the Car.cost variable is just ONE for the lifecycle of the program.
Good luck !
来源:https://stackoverflow.com/questions/7824323/can-two-copies-of-class-variable-exist