我正在学习不变性,但我无法准确地消化它是如何工作的。所以为了让我理解不变性,我创建了一个测试程序。
功能getArray(Box b)
将创建Box
个对象的ArrayList。
Expected output: Actual output:
Output Output
a is 5 a is 5
b is 10 b is 10
Output Output
a is 0 a is 4
b is 0 b is 40
Output Output
a is 1 a is 4
b is 10 b is 40
Output Output
a is 2 a is 4
b is 20 b is 40
Output Output
a is 3 a is 4
b is 30 b is 40
Output Output
a is 4 a is 4
b is 40 b is 40
逻辑:
public class Box {
static int a;
static int b;
public Box() {
a = 5;
b = 10;
}
public int getA() {
return a;
}
public void setA(int x) {
a = x;
}
public int getB() {
return b;
}
public void setB(int x) {
b = x;
}
public void display() {
System.out.println("Output");
System.out.println("a is " + a);
System.out.println("b is " + b);
System.out.println();
}
}
主类
import java.util.ArrayList;
public class Check {
public static void main(String[] args) {
Box b = new Box();
b.display();
ArrayList<Box> arr2 = new ArrayList<Box>();
arr2 = getArray(b);
for (int i = 0; i < arr2.size(); i++) {
arr2.get(i).display();
}
}
public static ArrayList<Box> getArray(Box b) {
ArrayList<Box> arr = new ArrayList<Box>();
for (int i = 0; i < 5; i++) {
b.setA(i);
b.setB(i * 10);
arr.add(b);
}
return arr;
}
}
如何以获得所需输出的方式更改逻辑?我们如何决定编辑代码的方式和位置以确保不变性?
答案 0 :(得分:0)
这将是一个不可变的:
public final class Box {
final int a;
final int b;
public Box(int a, int b) {
this.a = a;
this.b = b;
}
}
然后你的数组方法是:
public static ArrayList<Box> getArray(Box b) {
ArrayList<Box> arr = new ArrayList<Box> ();
for(int i =0 ;i <5; i++) {
arr.add(new Box(i, i*10));
}
return arr;
}
数据成员被声明为final
,因为它们是不可变的,所以getter是没有意义的,而setter只是毫无意义。
该类声明为final
,因此您无法将其子类化。
答案 1 :(得分:0)
简而言之,不可变对象是一个对象,其状态在创建后无法修改。你的不可变Box对象看起来像这样:
public final class Box {
private final int a;
private final int b;
public Box(int a, int b) {
this.a = a;
this.b = b;
}
public int getA() {
return a;
}
public int getB() {
return b;
}
public void display() {
System.out.println("Output");
System.out.println("a is " + a);
System.out.println("b is " + b);
System.out.println();
}
}
请注意,在构造Box实例期间,变量a
和b
只分配了一次。没有setter,因为Box的不变性意味着它的状态(包括变量a
和b
)在其生命周期内不会改变。
final
和a
前面的b
关键字意味着您必须将其分配一次。除非你特别需要它们,否则所有变量都是最终的,这被认为是一种好的做法。但对于一个不可变的对象,它是必不可少的。
您使用的是static
关键字。静态与不变性无关。这意味着变量在Box类的所有实例之间共享。在我的示例中,每个Box实例都有自己的a
和b
副本,因为我没有将它们设置为静态。
为了把它包起来,我将给出一个具有所需输出的主类的例子:
public class Check {
public static void main(String[] args) {
final List<Box> arr2 = getArray();
for (int i = 0; i < arr2.size(); i++) {
arr2.get(i).display();
}
}
public static ArrayList<Box> getArray() {
final ArrayList<Box> arr = new ArrayList<>();
for (int i = 0; i < 5; i++) {
final Box box = new Box(i, i * 10);
arr.add(box);
}
return arr;
}
}
请注意,在循环的每次迭代中都会创建一个新的box实例。