【问题标题】:Do final (constant) instance (non-static) variables act like class (static) variables?最终(常量)实例(非静态)变量是否像类(静态)变量一样?
【发布时间】:2012-03-14 09:53:07
【问题描述】:

在以下示例中,变量 b 被声明为 final,但不是 static。这意味着它是一个常量实例变量。但是,因为它是常量,所以 Passenger 对象都不能改变它的值。那么声明static并使其成为类变量不是更好吗,这样所有实例化的对象都只能使用一个副本?

class Passenger {
    int a;
    final int b = 0;

    void drive() {
        System.out.println("I'm driving!");
    }
}

【问题讨论】:

  • 是的,你完全正确。

标签: java variables scope constants


【解决方案1】:

final 但非static 变量的目的是拥有一个对象范围的常量。应该在构造函数中初始化:

class Passenger {
    final int b;

    Passenger(int b) {
        this.b = b;
    }
}

如果您总是将常量字面值 (0) 分配给 final 变量,则没有多大意义。最好使用static,这样您就只有b 的一个副本:

static final int b = 0;

顺便说一句,我不认为使用默认访问修饰符是您的意图。

【讨论】:

  • 谢谢!没有在构造函数中考虑对象范围的常量和初始化。
  • 是的,我在这个例子中省略了访问修饰符。
【解决方案2】:

这取决于 b 的目的。通常,常量用于特定目的。如果将其设为静态,则可能会在该类的某些实例中意外更改它,这将影响所有其他实例。

【讨论】:

  • 但是静态变量也可以声明为final。这样可以防止意外修改。
【解决方案3】:

如果您有多个 Passenger 类实例,我会选择将其设为静态。虽然这在谈论 int 变量时没有什么好处,但如果您有复杂的对象,这可以节省一些内存。这是因为一个静态变量属于一个类,而不是一个实例,因此它的内存空间只会被保留一次,它会被类对象本身引用,而不是被实例引用。当然,您应该知道,将b 作为静态变量意味着对该变量所做的更改将反映在访问该变量的所有类上,但是由于您将其设置为final,这不会是案子。

另请注意,使用您编写的代码,与Passenger 相同包中的类将能够通过通过Passenger.b 访问它来读取b 值(如果是静态的)。

【讨论】:

  • 是的,为大变量节省内存正是我将其声明为静态的原因。在此示例中,我省略了访问修饰符。我怀疑很多人会注意到:D
  • 当然,如果你有复杂的对象,记住只有引用才是最终的,但除非你使它们不可变,否则你仍然可以通过操作方法来改变内部状态,如果有的话。这样,由于对象在所有实例之间共享,内部状态的变化将反映在该对象的所有读取器上。
  • 哦,我明白你的意思了。 stackoverflow.com/questions/1249917/…
【解决方案4】:

在 java 中,static 属性基本上意味着:与类型本身相关联,而不是与类型的实例相关联

换句话说,您可以在不创建该类型的实例的情况下引用静态变量...而在仅使用final 的情况下,您需要实例化该类。

所以,是的,要回答你的问题,我会说你是对的。 :)

【讨论】:

    【解决方案5】:

    final 原语与static final 原语相同(除了更高效)

    final 对不可变对象的引用与 static final 的引用相同。

    对可变对象的final 引用与对同一对象的static final 引用不同。

    final int i = 0;
    // same as
    static final int = 0;
    
    final String hi = "Hello";
    // same as
    static final String hi = "Hello";
    
    final List<String> list = new ArrayList<String>();
    // is NOT the same as
    static final List<String> list = new ArrayList<String>();
    

    最后一个例子唯一相同的地方是当你有一个单例时。在编写单例时混淆静态和非静态字段和方法是相当普遍的,因为区别并不明显。 :|

    【讨论】:

      【解决方案6】:

      final 变量是在您需要常量时定义的,因此您只需赋值一次。 相反,使用static,您定义了一个由该类型的所有对象共享的变量(如全局变量),并且它与某个对象本身无关。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多