我的教授說他們完全不同,但我讀他們很相似。我不知道他指的是什麼背景「不同」。 如果這個問題已經被回答,只是鏈接它。謝謝。有人可以解釋深層複製和防禦性複製之間的區別嗎?
1
A
回答
1
深層複製:一種對象複製技術:深層複製結構中的所有數據。產生對象的深層副本的「苛刻」方法是序列化然後反序列化它。對於樹木,通常遞歸複製是一種有效的解決方案。
防禦性拷貝:保護內部數據的操作結果。通常它是一個深度或淺度的副本,用於防止通過內部參考結果進行不必要的訪問。
public int[] getValues() {
return Arrays.copyOf(values, values.length);
}
在一般情況下,你應該使用防禦性副本,以保護內部數組,集合或其他結構。如果我們簡單地返回(對數組的引用),用戶可以修改我們的內部結構!
查看示例。
湯姆寫了一個類懶洋洋緩存的Integer
收集的一些彙總:
public class CachedIntegerAggregator {
private List<Integer> integers;
private boolean isSumCalculated = false;
private int sum = 0;
private boolean isMultiCalculated = false;
private int multi = 0;
public CachedIntegerAggregator(Integer... integers) {
this(Arrays.asList(integers));
}
public CachedIntegerAggregator(Collection<Integer> integers) {
this.integers = new ArrayList<Integer>(integers);
}
public List<Integer> getIntegers() {
return integers;
}
public int getSum() {
if (!isSumCalculated) {
sum = 0;
for (Integer integer: integers) {
sum += integer;
}
isSumCalculated = true;
}
return sum;
}
public int getMulti() {
if (!isMultiCalculated) {
multi = 1;
for (Integer integer: integers) {
multi *= integer;
}
isMultiCalculated = true;
}
return multi;
}
}
傑裏使用上述類以這樣的方式
CachedIntegerAggregator aggregator = new CachedIntegerAggregator(2, 3, 4);
// hm, what is the sum?
System.out.println(aggregator.getSum());
// let's print of integers
List<Integer> integers = aggregator.getIntegers();
System.out.println(integers);
// now, see the double
int size = integers.size();
for (int i = 0; i < size; i++) { // (oops! this changes internal data!)
integers.set(i, integers.get(i) * 2);
}
System.out.println(integers);
// hm, see sum and multi
System.out.println(aggregator.getSum());
System.out.println(aggregator.getMulti()); // (oops! total inconsistency!)
輸出:
9
[2, 3, 4]
[4, 6, 8]
9
192
主要問題是什麼?湯姆泄漏了一個可變的內部結構。解決辦法是什麼?在getIntegers()
做它的一個副本返回之前:
public List<Integer> getIntegers() {
return new ArrayList<Integer>(integers);
}
在某些情況下,一個不可變的包裝是對子級也沒錯:
public List<Integer> getIntegers() {
return Collections.unmodifiableList(integers);
}
性能?一般來說,不要擔心。快速創建對象是Java的主要優勢之一。當然,有複雜的結構,將被低效地複製。在這種情況下,您可以使用寫入時複製技術。一些大數據結構實現已經建立在寫入時複製支持上,如BigList。
相關問題
- 1. 有人可以解釋Java AudioFormat和AudioFileFormat之間的區別嗎?
- 2. 有人可以解釋兩個查詢之間的區別嗎?
- 3. 數子類的防禦性複製
- 4. 淺層和深層複製
- 5. 有人可以解釋Django中的HttpResponse和HttpResponseRedirect之間的區別嗎?
- 6. 有人可以解釋我ID3和CART算法之間的區別嗎?
- 7. 保留和複製之間的區別?
- 8. 任何人都可以解釋我的級別控制器和方法級別控制器之間的區別。
- 9. 複製/ a和複製之間的區別/ b
- 10. 「複製」和「複製限定名稱」之間的區別
- 11. 有人可以解釋&和&&的區別嗎?
- 12. 有人可以解釋@Remote/@Local或ejb中的@Stateless之間的區別嗎?
- 13. 有人可以解釋這兩個JS代碼片段之間的區別嗎?
- 14. 有人可以解釋表達式屬性名稱和表達式屬性值之間的區別嗎?
- 15. Java的淺層和深層複製JLS
- 16. 深層複製VS淺複製
- 17. 彈性搜索中多場和複製之間的區別?
- 18. 有人可以解釋測試場景和測試用例之間的區別
- 19. 關於不可變類防禦性複製
- 20. 可以配置mysql複製以防止複製drop database嗎?
- 21. 有人可以解釋我這個JavaScript對象「複製」行爲
- 22. 有人可以解釋這裏的區別嗎?
- 23. 有人可以解釋這兩個Youtube網址的區別嗎?
- 24. 有人可以解釋兩個Python命令的區別嗎?
- 25. 任何人都可以解釋這兩個循環之間的區別嗎?
- 26. 深層複製Javascript數組與性能
- 27. 有人可以解釋'混帳恢復...'
- 28. 深層複製錯誤
- 29. C++淺/深層複製?
- 30. 有人可以解釋嗎?
只是目的。深層複製意味着您複製每個元素(不指定原因),而防禦複製意味着您複製以防止其他人訪問同一對象(例如,爲了線程安全)。 – markspace
我可以開車去豐田工作,但開車上班與豐田完全不一樣。一種是汽車,一種是使用汽車的方式。深層副本是一種副本,防禦副本是使用副本的一種方式。 – Radiodef