类变量可以存在两个副本吗?
我有一个类 Car
,它有一个类作用域变量成本,我知道这在实践中是一个坏主意,只是试图了解公共作用域类变量的影响。
cost 是否可以被 Car 类的所有对象、Car.cost 的引用、所有类加载器访问和修改,或者我是否应该知道可能存在多个 Car.cost 副本的情况?在任何给定情况下都会只有一个 Car.cost
吗?
public class Car{
public static int cost;
public Car(int cost){
cost = cost;
}
}
public static void main(String args[]){
Car car = new Car(2);
}
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
构造函数中的局部作用域成本(参数)隐藏了类作用域成本(静态)。
将构造函数更改为:
不要使用
this.cost
寻址类作用域变量(静态成本)。相反,使用类名静态地寻址它。编辑:这是一个简单的演示:
当您将其放入 ecliipse 中时,您应该在
System.out.println(costTest.cost);
行上看到一条警告,内容类似于“静态字段 CostTest” .cost 应以静态方式访问”。The local scope cost (the parameter) in the Constructor hides the Class scope cost (the static).
Change the constructor to be this:
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:
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".通过将
cost
字段指定为static
,您表示无论创建了多少个 Car 类(在一个进程内),该变量都只会有一个共享实例.) 是的,这些实例中的任何一个都将能够修改该单个共享字段,并且由于您将其公开,因此有权访问 Car 类的任何其他客户端代码也将能够修改该字段。 (可能使用相同类的其他进程将拥有自己的静态类成员副本,并且无法跨进程边界“看到”。)从语义上讲,如果我正确推断出 Car 和 cost 的含义,那么您就可以不想使用静态除非您希望所有汽车的成本相同。在现实世界中,由于装饰、选项等原因,即使在同一品牌、同一型号的汽车之间,汽车的成本也是一个高度可变的属性。
By specifying the
cost
field asstatic
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 theCar
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.
这里唯一的问题是是否涉及多个类加载器。在这种情况下,每个 ClassLoader 的上下文中都可以有一个给定类的实例,然后该实例将具有与其关联的一组单独的静态字段。大多数(如果不是全部)Servlet & J2EE 容器使用多个
ClassLoader
,通常每个 Web 应用程序一个。ClassLoader
通常是分层的,这样您就可以访问从父ClassLoader
加载的类。这样,如果您确实需要跨多个 Web 应用程序的全局单例,您通常会尝试将单例加载到根ClassLoader
中,以便可以在任何地方访问它。查看此描述以获取示例: http://vanillajava .blogspot.com/2011/07/java-secret-loading-and-unloading.html
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 eachClassLoader
which would then have a separate set of static fields associated with it. Most, if not all, Servlet & J2EE containers use multipleClassLoaders
, typically one per web-app.The
ClassLoaders
are typically hierarchical, such that you can access classes loaded from a parentClassLoader
. In this way, if you really need a global singleton across multiple web-apps, you generally try to have your singleton loaded in a rootClassLoader
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
这里不能存在多个 Car.cost 变量,因为 Car.cost 可以从类路径中加载的每个类访问(因为它同时是公共和静态的)。
当某个东西在面向对象语言中是“公共静态”时,这意味着它可以被视为过程语言中的全局变量。几乎是一样的。
因此,总而言之,Car.cost 变量的实例对于程序的生命周期来说只是一个。
祝你好运 !
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 !
每个加载的类只有一个静态
cost
变量实例。但请注意,根据类加载器,一个类可能会被加载多次。顺便说一句,这不会像你想象的那样:
在这里你将参数分配给它自己(如果你把它设置为最终的,你应该得到一个编译器错误),而不是分配给静态变量的参数。这也被称为影子和不良做法。
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:
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.