为什么默认情况下所有最终变量都不是静态的?

时间:2017-06-28 13:20:14

标签: java static final

为什么您是否需要非静态上下文中的Output(Complications, "Complications.pdf") 变量?编译器是否自动为所有final变量分配static

修改:我知道finalstatic之间的区别,我要问的是,在您需要final而不是final int x的情况下是否存在任何问题。当您无法修改时,为什么在每个实例中都需要static final int x的副本?

5 个答案:

答案 0 :(得分:1)

因为使final类的字段更有意义。

实际上,这应该是您的默认。如果您有充分的理由稍后更改其值,则只会在字段中删除final关键字。

推理很简单:您希望编译器在您忘记初始化字段时告诉您。除此之外:您甚至可以在构造函数中初始化字段。因为在所有其他代码中您可以确定所有字段都已正确初始化。

换句话说:你想做一些研究,为什么immutability被视为类的正面属性!

答案 1 :(得分:1)

如果您希望在施工时仅允许分配值,则使用关键字final

public class Person {
    public final String name;

    public Person(String name) {
        this.name = name;
    }
}

Person p = new Person("a");
p.name = "newName"; // COMPILE ERROR name is marked as "final" thus can not be changed.
  

何时需要final int x而不是static final int x?

考虑这些课程:

public class OriginConstants {
      // static final fields allows to access constants via class accessor i. e. OriginConstants.x (no need to create instance)
      public static final int x = 0;
      public static final int y = 0;
}

public class ImmutablePoint {
    public final int x;
    public final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class MutablePoint {
    public int x;
    public int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

用法示例

// create immutable point shifted from coordinate system origin by 5
ImmutablePoint ip = new ImmutablePoint(OriginConstants.x + 5, OriginConstants.y + 5);

// updating point coordinate by 10
ip.x += 10; // COMPILE ERROR 
ip.y += 10; // COMPILE ERROR

// we cannot modify final fields, but we can create new instance with shifted coordinates
ImmutablePoint shiftedIp = new ImmutablePoint(ip.x + 10, ip.y + 10);

// create mutable point shifted from coordinate system origin by 5
MutablePoint mp = new MutablePoint(OriginConstants.x + 5, OriginConstants.y + 5);

// updating point coordinate by 10
ip.x += 10; // OK
ip.y += 10; // OK

我会对一些无法及时更改的坐标使用不可变点。假设我们有高度= 100,宽度= 100的画布。我们可以创建如下的辅助常量点:

public class Canvas {
    public static final int HEIGHT = 100;
    public static final int WIDTH = 100;

    // anchor points
    public static final ImmutablePoint topLeft = new ImmutablePoint(0,0);
    public static final ImmutablePoint topRight = new ImmutablePoint(Canvas.WIDTH, 0);
    public static final ImmutablePoint bottomLeft = new ImmutablePoint(0, Canvas.HEIGHT);
    public static final ImmutablePoint bottomRight = new ImmutablePoint(Canvas.WIDTH, Canavas.HEIGHT);
}

这样我们可以肯定,topLeft总是0,0并且不能因为某些错误而改变。

答案 2 :(得分:1)

最终变量的一个重要用法是immutable objects。不可变对象是一旦创建并初始化然后从未变异的对象。 您可以拥有此类对象的许多实例,因此静态字段没有意义。但由于这些对象是不可变的,因此必须使所有字段都是最终的。

简单不可变类的示例:

class User {
  private final String name;

  public User(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}

答案 3 :(得分:0)

static表示您不必拥有类的实例来使用该变量。

例如Math.PI,您不需要实例化Math类来使用PI的值,因此它是静态的。它必须是恒定的,所以它也是最终的。

如果您没有final,则表示变量应该是该实例的常量。初始化类后,它是最终的,无法更改。如果要在不必实例化类的情况下使用常量,请添加static

答案 4 :(得分:0)

这样做是为了防止方法修改对象实例中的状态。它们被称为不可变对象,通常简化您的编程,因为它们将简化您的测试场景。

这里的答案很好: What is meant by immutable?

在您的示例中,您将执行以下操作:

public class Person {
    public final String name;

    public Person(String name) {
        this.name = name;
    }
    public Person rename(String name) {
        return new Person(name)
    }

 }