在Java中,两个不同的双对象可以共享相同的内存位置吗?

在Java中,两个不同的双对象可以共享相同的内存位置吗?,java,double,heap-memory,Java,Double,Heap Memory,在我的代码中有一些类似于下面的类,不是确切的类,而是类似的结构 class Shop { Item item; Service service; } class Item { ... Amount amt; ... } class Service { ... Amount amt; ... } class Amount { Double value; String currencyCode; } 我遇到了一个非常奇怪的情况,在item对象中更

在我的代码中有一些类似于下面的类,不是确切的类,而是类似的结构

class Shop {
  Item item;
  Service service;
}

class Item {
  ...
  Amount amt;
  ...
} 

class Service {
  ...
  Amount amt;
  ...
} 

class Amount {
  Double value;
  String currencyCode;
}

我遇到了一个非常奇怪的情况,在item对象中更改Amount的值字段就是在service对象中更改Amount的值字段。
Java是否以某种方式为这两个对象共享相同的内存?如果是,有什么办法可以避免这种情况

2个不同的双重对象?没有

但是两个不同的对象一个服务对象和一个项目对象当然都可以有一个变量,它的值引用。如果你是C语言的,它是一个指针,我们在java中称它们为“引用”,数量相同的实例

考虑所有变量,除了基本体珍宝贴图和所有对象珍宝

如果我在海滩上埋些财宝,画一张我的财宝的地图,那是一回事。如果我在地图上涂鸦,然后给你这个副本,那么你对地图副本做什么都无关紧要。把它扔进碎纸机,我不在乎;在java中,我不会注意到:如果该项为'amt=null',则根本不会影响服务对象的amt

但是,如果你拿了一份藏宝图,跟着它,把你在那里找到的宝藏挖出来,然后把它砸成碎片。。。我会注意到的

2张藏宝地图,但只有一件藏宝

2个可用的修复程序:

在将可变对象移交给其他代码之前,或通常首选的情况下,制作可变对象的防御性副本:

使对象不可变,Amount对象的构造函数应设置其值和currencyCode,然后不允许这些值和currencyCode发生变化;值和currencyCode变量应声明为最终变量

不变的物体就像坚不可摧的宝藏。那么大家都知道它埋在哪里就不重要了,他们只能看着它,不能再改变它了


注:将货币价值加倍是一个非常愚蠢的想法;并不是所有存在的数字都能准确地表示为双精度数。你应该储存美分,所以,长美分;或者,您也可以使用int-cents;。其中,“cent”是您所代表的货币代码允许在银行等处转账的最小原子量。美元是一美分,欧元也是,日元是1日元。比特币为1 satoshi 0.00000001 BTC——所有货币都有一些实际上不可分割的金额。代表那些。作为一个长期的伙伴。塔达!现在,舍入行为很容易理解,与double不同。

这意味着您使用的是相同的AmountThank实例,在深入查看代码后,我发现两个对象都引用了相同的对象。正如我在问题中所说的,实际的代码比上面所示的更复杂,因此必须正确地调试它才能找到相同的引用。我知道使用Double来表示金钱是不正确的,但它是一种遗留代码,目前在全公司都在使用,所以现在必须这样使用。@ScaryWombat BigDecimal非常复杂:[1]试着用1美元除以3人的大小数。你会得到一个例外。这在某些方面是好的,但它确实表明BigDecimal不是银弹。[2] 0.1等于0.10吗?两者都具有代表性![3] 那么2个bd代表相同的数字,但比例不同呢?相同的BigDecimal是火箭筒,而且很难使用。渴望表示原子单位的效果更好。@ScaryWombat编写并执行这个java:BigDecimal.ONE.divideBigDecimal.valueOf3.0@它会产生33个恐怖分子。这同样有问题。真正的答案是:这取决于在此上下文中“除以”的含义。如果这是一笔3人应该向银行支付的费用,而你就是银行,那么你最想要的答案可能是“汇总”,每人支付34美分。如果这是一个平均分配的好处,那么它是“向下舍入”:每个人得到33。备选答案:随机挑选一个人。那个人付34美分,另外两个付33美分。等等线索是:无论如何,你必须用原子单位思考,所以BIgDecimal绝对没有任何用处。