【问题标题】:Static Attributes in JavaJava 中的静态属性
【发布时间】:2014-01-27 17:14:40
【问题描述】:
public class Ride {
   public static String name;
   public static int ticketsRequired;
   public static float heightRequirement;

   public Ride(String name, int ticketsRequired, float heightRequirement) {
      this.name = name;
      this.ticketsRequired = ticketsRequired;
      this.heightRequirement = heightRequirement;
   }

   public static void main(String args[]) { 
      Ride coaster, tosser; 
      coaster = new Ride("Roller Coaster", 6, 4.25f);
      tosser = new Ride("Tummy Tosser", 7, 4.9f);
   }
}

不管我叫什么,它只取最后一个实例“tosser”的值,这是为什么呢?我搞砸了属性吗?

【问题讨论】:

  • 你认为static 字段是/做什么?
  • @Sotirios Delimanolis 我认为如果我们想在另一个类中使用属​​性,我们需要将它们声明为静态,对吧?
  • 错了,阅读documentation
  • 但是我尝试将这些属性声明为非静态,当我在另一个类中使用“something.ticketRequired”时,它说“不能从静态上下文引用非静态变量ticketRequired”。跨度>
  • 阅读我之前发布的链接。如果您不打算使用它,为什么还要将参数传递给您的方法?

标签: java constructor static


【解决方案1】:

你的类变量是static,这意味着整个类只有一个副本。您正在用您创建的每个新对象覆盖构造函数中的值。

要为每个对象设置不同的值,它们必须不是static

public String name;
public int ticketsRequired;
public float heightRequirement;

它们是 public 的事实意味着它们可以从任何其他类访问。​​

但这也表明您的类没有正确封装。您可以使您的字段可访问,即使它们是 private,但定义 public 访问器方法,例如getName().

示例,其中一个变量:

private String name;

public String getName() { return name; }

【讨论】:

    【解决方案2】:

    静态变量是类变量。每个类只有一个静态变量副本。

    您实际上是在覆盖静态变量。

    通过从所有三个变量中删除 static 关键字,您现在将拥有实例变量。类的每个对象都有自己的实例变量副本。

    所以三个声明应该是:

    public String name;
       public int ticketsRequired;
       public float heightRequirement;
    

    现在每个对象都有自己的这些变量的副本,您将获得正确的输出。

    【讨论】:

      【解决方案3】:

      静态变量是类变量。这些变量是在加载类时加载的。其中有一个单独的内存位置,称为静态池,不在堆中。 JVM 为每个被称为对象状态的更新维护变量的副本。这种状态将在每个实例级别上升级,这些实例变量是实例变量。但是当涉及到静态变量时,在类加载时只会保留一份副本。此副本将得到更新。在您的示例中,所有三个变量都是在静态池中创建的,并在 Ride 类加载时加载。您对该副本进行了 3 次更新。因此,最终更新将替换为之前的 2 个更新。

      【讨论】:

        【解决方案4】:

        *“但是我尝试将这些属性声明为非静态,当我在另一个类中使用“something.ticketRequired”时,它说“不能从静态上下文引用非静态变量ticketRequired””

        静态意味着这个变量对于这个类的所有实例都是相同的,所以

        public static String name;
        

        对于 Ride 类的每个 Object 将是相同的,因此 Coaster.name == tosser.name,因为它们引用相同的 Object。如果你为它分配一个新的字符串,它会为所有实例更新它。

        静态变量也可以通过其类名访问,因此您甚至不需要任何对象来引用该变量:

        System.out.println(Ride.name); //This works too
        

        “不能从静态上下文引用非静态变量ticketRequired”

        这意味着您正在尝试从静态上下文访问成员变量(=非静态变量),因此没有任何对象可以引用它。

        如果你有一个非静态变量,你需要一个对象来引用它:

        public String name; //non-static
        
        System.out.println(Ride.name); //doesn't work, since name is not static
        System.out.println(coaster.name); //does work, prints "Roller Coaster"
        System.out.println(tosser.name);  //does work, prints "Tummy Tosser" 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-04-18
          • 2012-10-01
          • 1970-01-01
          • 2011-03-10
          • 1970-01-01
          • 2014-12-21
          • 2014-03-03
          相关资源
          最近更新 更多