Java 类变量是否可以存在两个副本?

Java 类变量是否可以存在两个副本?,java,static-members,Java,Static Members,我有一辆具有类范围可变成本的类车,我知道这在实践中是个坏主意,只是试图了解公共范围类变量的影响 cost是否可以通过所有类装入器中的所有Car对象、Car.cost引用访问和修改,或者我是否应该知道可能存在多个Car.cost副本的情况?在任何特定情况下,是否只有一辆车的成本 public class Car{ public static int cost; public Car(int cost){ cost = cost; } } public static voi

我有一辆具有类范围可变成本的类车,我知道这在实践中是个坏主意,只是试图了解公共范围类变量的影响

cost是否可以通过所有类装入器中的所有Car对象、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);      
}

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

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

当您将其放入ECLIPSE中时,应该会在System.out.printlncostTest.cost行中看到一条警告;也就是说,应该以静态方式访问静态字段CostTest.cost。

本地范围成本构造函数中的参数隐藏了静态的类范围成本。 将构造函数更改为:

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;
    }
}
当您将其放入ECLIPSE中时,应该会在System.out.printlncostTest.cost行中看到一条警告;也就是说,应该以静态方式访问静态字段CostTest.cost。

通过将成本字段指定为静态字段,您的意思是,无论在一个流程中创建了多少汽车类,该变量都将只有一个共享实例。是的,这些实例中的任何一个都将能够修改这个单一的共享字段,而且由于您将其公开,所以任何其他可以访问Car类的客户端代码也将如此。其他可能使用相同类的进程将拥有它们自己的静态类成员副本,并且无法跨越进程边界进行查看

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

通过将成本字段指定为静态,您的意思是,无论在一个流程中创建了多少汽车类,该变量都将只有一个共享实例。是的,这些实例中的任何一个都将能够修改这个单一的共享字段,而且由于您将其公开,所以任何其他可以访问Car类的客户端代码也将如此。其他可能使用相同类的进程将拥有它们自己的静态类成员副本,并且无法跨越进程边界进行查看


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

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

作为旁注,这不会像你想的那样:

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

在这里,您将参数分配给它自己,如果将其设置为final,则应该得到一个编译器错误,而不是静态变量的参数。这被称为隐藏,也是一种糟糕的做法。

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

作为旁注,这不会像你想的那样:

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

在这里,您将参数分配给它自己,如果将其设置为final,则应该得到一个编译器错误,而不是静态变量的参数。这被称为跟踪,也是不好的做法。

此处不存在多个Car.cost变量,因为Car.cost可以从类路径中加载的每个类中访问,因为它同时是公共的和静态的

当某些东西在OO语言中是“公共静态”时,这意味着它可以在过程语言中被视为全局变量。几乎一样

因此,作为结论,Car.cost变量的实例只是程序生命周期中的一个实例


祝你好运

此处不能存在多个Car.cost变量,因为Car.cost可以从类路径中加载的每个类中访问,因为它同时是公共的和静态的

当某些东西在OO语言中是“公共静态”时,这意味着它可以在过程语言中被视为全局变量。几乎一样

因此,作为结论,Car.cost变量的实例只是程序生命周期中的一个实例


祝你好运

这里唯一的问题是如果 涉及多个类装入器。在这种情况下,在每个类加载器的上下文中可以有一个给定类的实例,该实例将有一组单独的与之关联的静态字段。大多数(如果不是全部的话)Servlet和J2EE容器使用多个类加载器,通常每个web应用一个

类加载器通常是分层的,因此您可以访问从父类加载器加载的类。这样,如果您确实需要跨多个web应用程序的全局单例,您通常会尝试将单例加载到根类加载器中,以便可以在任何地方访问它


查看下面的描述以获得一个示例:

这里唯一的问题是涉及多个类加载器。在这种情况下,在每个类加载器的上下文中可以有一个给定类的实例,该实例将有一组单独的与之关联的静态字段。大多数(如果不是全部的话)Servlet和J2EE容器使用多个类加载器,通常每个web应用一个

类加载器通常是分层的,因此您可以访问从父类加载器加载的类。这样,如果您确实需要跨多个web应用程序的全局单例,您通常会尝试将单例加载到根类加载器中,以便可以在任何地方访问它

请查看此说明以获取示例:

这可能会引起兴趣:可能会引起兴趣的重复:可能会引起兴趣的重复