为什么您是否需要非静态上下文中的Output(Complications, "Complications.pdf")
变量?编译器是否自动为所有final
变量分配static
?
修改:我知道final
和static
之间的区别,我要问的是,在您需要final
而不是final int x
的情况下是否存在任何问题。当您无法修改时,为什么在每个实例中都需要static final int x
的副本?
答案 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)
}
}