两个不同的 Double 对象可以在 Java 中共享相同的内存位置吗?
Can two different Double objects share same memory location in Java?
我的代码中有一些 类 类似的内容(不完全是 类,但结构相似)。
class Shop {
Item item;
Service service;
}
class Item {
...
Amount amt;
...
}
class Service {
...
Amount amt;
...
}
class Amount {
Double value;
String currencyCode;
}
我 运行 陷入非常奇怪的境地,在 item
对象中更改 Amount
的 value
字段正在更改 Amount
的 value
字段] 在 service
对象中。
Java 是否以某种方式为这两个对象共享相同的内存?如果是,避免这种情况的解决方案是什么?
2个不同的双重对象?编号
但是 2 个不同的对象(一个 Service 对象和一个 Item 对象)肯定都可以有一个变量,其值引用(如果你来自 C,它是一个指针,我们只是称它们为 'references' java) 相同的 Amount 实例。
考虑所有变量(原始类型除外)藏宝图,以及所有对象宝藏。
如果我在海滩上埋了一些宝藏,并为我的宝藏画了一张地图,那是一回事。如果我然后潦草地写下我的地图的 副本 并给你这个副本,那么你对地图的副本做什么都没有关系。随心所欲地把它扔进碎纸机;我不会注意到(在 java 中:如果 Item 'amt = null',那根本不会影响服务对象的 amt。
但是,如果你拿着你的藏宝图副本,跟着它,把你在那里找到的宝藏挖出来,然后把它砸成碎片……我会注意到的。
2张藏宝图,但只有一张宝藏。
2 个修复可用:
在将可变对象移交给其他代码之前制作可变对象的防御性副本,或者通常首选:
让你的对象不可变,Amount 对象的构造函数应该设置它的值和货币代码,然后它不应该允许这些改变; value
和 currencyCode
变量应声明为最终变量。
不可变对象就像坚不可摧的宝藏。那么大家知道它埋在哪里已经无所谓了,只能看看,不能再改变了。
注意:将货币价值加倍是一个非常非常愚蠢的想法;并非每个存在的数字都可以准确地表示为双精度数。您应该改为存储美分(因此,long cents;
或者您可以使用 int cents;
。其中 'cent' 是您所代表的货币代码允许在例如银行转账的最小原子数等等。因此,对于美元来说,它是一分钱,对于欧元来说也是一样,对于日元来说,它是 1 日元。对于比特币来说,它是 1 satoshi(0.00000001 BTC)——所有货币都有一些有效不可分割的数量。代表那些。作为 long。Tada!现在舍入行为很容易理解,与双打不同。
我的代码中有一些 类 类似的内容(不完全是 类,但结构相似)。
class Shop {
Item item;
Service service;
}
class Item {
...
Amount amt;
...
}
class Service {
...
Amount amt;
...
}
class Amount {
Double value;
String currencyCode;
}
我 运行 陷入非常奇怪的境地,在 item
对象中更改 Amount
的 value
字段正在更改 Amount
的 value
字段] 在 service
对象中。
Java 是否以某种方式为这两个对象共享相同的内存?如果是,避免这种情况的解决方案是什么?
2个不同的双重对象?编号
但是 2 个不同的对象(一个 Service 对象和一个 Item 对象)肯定都可以有一个变量,其值引用(如果你来自 C,它是一个指针,我们只是称它们为 'references' java) 相同的 Amount 实例。
考虑所有变量(原始类型除外)藏宝图,以及所有对象宝藏。
如果我在海滩上埋了一些宝藏,并为我的宝藏画了一张地图,那是一回事。如果我然后潦草地写下我的地图的 副本 并给你这个副本,那么你对地图的副本做什么都没有关系。随心所欲地把它扔进碎纸机;我不会注意到(在 java 中:如果 Item 'amt = null',那根本不会影响服务对象的 amt。
但是,如果你拿着你的藏宝图副本,跟着它,把你在那里找到的宝藏挖出来,然后把它砸成碎片……我会注意到的。
2张藏宝图,但只有一张宝藏。
2 个修复可用:
在将可变对象移交给其他代码之前制作可变对象的防御性副本,或者通常首选:
让你的对象不可变,Amount 对象的构造函数应该设置它的值和货币代码,然后它不应该允许这些改变;
value
和currencyCode
变量应声明为最终变量。
不可变对象就像坚不可摧的宝藏。那么大家知道它埋在哪里已经无所谓了,只能看看,不能再改变了。
注意:将货币价值加倍是一个非常非常愚蠢的想法;并非每个存在的数字都可以准确地表示为双精度数。您应该改为存储美分(因此,long cents;
或者您可以使用 int cents;
。其中 'cent' 是您所代表的货币代码允许在例如银行转账的最小原子数等等。因此,对于美元来说,它是一分钱,对于欧元来说也是一样,对于日元来说,它是 1 日元。对于比特币来说,它是 1 satoshi(0.00000001 BTC)——所有货币都有一些有效不可分割的数量。代表那些。作为 long。Tada!现在舍入行为很容易理解,与双打不同。