类变量可以存在两个副本吗?

发布于 2024-12-11 05:47:59 字数 396 浏览 0 评论 0原文

我有一个类 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不弃不离 2024-12-18 05:48:00

构造函数中的局部作用域成本(参数)隐藏了类作用域成本(静态)。
将构造函数更改为:

public Car(int cost)
{
  Car.cost = cost;
}

不要使用 this.cost 寻址类作用域变量(静态成本)。相反,使用类名静态地寻址它。

编辑:这是一个简单的演示:

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;
    }
}

当您将其放入 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:

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".

云柯 2024-12-18 05:48:00

通过将 cost 字段指定为 static,您表示无论创建了多少个 Car 类(在一个进程内),该变量都只会有一个共享实例.) 是的,这些实例中的任何一个都将能够修改该单个共享字段,并且由于您将其公开,因此有权访问 Car 类的任何其他客户端代码也将能够修改该字段。 (可能使用相同类的其他进程将拥有自己的静态类成员副本,并且无法跨进程边界“看到”。)

从语义上讲,如果我正确推断出 Car 和 cost 的含义,那么您就可以不想使用静态除非您希望所有汽车的成本相同。在现实世界中,由于装饰、选项等原因,即使在同一品牌、同一型号的汽车之间,汽车的成本也是一个高度可变的属性。

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.

横笛休吹塞上声 2024-12-18 05:48:00

这里唯一的问题是是否涉及多个类加载器。在这种情况下,每个 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 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

芸娘子的小脾气 2024-12-18 05:48:00

这里不能存在多个 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 !

智商已欠费 2024-12-18 05:47:59

每个加载的类只有一个静态cost 变量实例。但请注意,根据类加载器,一个类可能会被加载多次。

顺便说一句,这不会像你想象的那样:

public Car(int cost)
{
  cost = 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:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文