Java?中的?clone(?)?和?new哪個(gè)效率更高
對象創(chuàng)建的幾種方法:
- 使用new關(guān)鍵字
- 使用clone方法
- 反射機(jī)制
- 反序列化
以上四種都可以產(chǎn)生java對象
- 1,3都會明確的顯式的調(diào)用構(gòu)造函數(shù)
- 2是在內(nèi)存上對已有對象的影印 所以不會調(diào)用構(gòu)造函數(shù)
- 4是從文件中還原類的對象 也不會調(diào)用構(gòu)造函數(shù)
何為clone()?
- 拷貝對象返回的是一個(gè)新的對象,而不是一個(gè)對象的引用地址;
- 拷貝對象已經(jīng)包含原來對象的信息,而不是對象的初始信息,即每次拷貝動作不是針對一個(gè)全新對象的創(chuàng)建。
clone()和new那個(gè)更快?
利用clone,在內(nèi)存中進(jìn)行數(shù)據(jù)塊的拷貝,復(fù)制已有的對象,也是生成對象的一種方式。前提是類實(shí)現(xiàn)Cloneable接口,Cloneable接口沒有任何方法,是一個(gè)空接口,也可以稱這樣的接口為標(biāo)志接口,只有實(shí)現(xiàn)了該接口,才會支持clone操作。有的人也許會問了,java中的對象都有一個(gè)默認(rèn)的父類Object。
Object中有一個(gè)clone方法,為什么還必須要實(shí)現(xiàn)Cloneable接口呢,這就是cloneable接口這個(gè)標(biāo)志接口的意義,只有實(shí)現(xiàn)了這個(gè)接口才能實(shí)現(xiàn)復(fù)制操作,因?yàn)閖vm在復(fù)制對象的時(shí)候,會檢查對象的類是否實(shí)現(xiàn)了Cloneable這個(gè)接口,如果沒有實(shí)現(xiàn),則會報(bào)CloneNotSupportedException異常。類似這樣的接口還有Serializable接口、RandomAccess接口等。
還有值得一提的是在執(zhí)行clone操作的時(shí)候,不會調(diào)用構(gòu)造函數(shù)。還有clone操作還會面臨深拷貝和淺拷貝的問題。關(guān)于這方面的問題,網(wǎng)上有很多的相關(guān)知識了,不再累述了。由于通過復(fù)制操作得到對象不需要調(diào)用構(gòu)造函數(shù),只是內(nèi)存中的數(shù)據(jù)塊的拷貝,那是不是拷貝對象的效率是不是一定會比new的時(shí)候的快。
答案:不是。顯然jvm的開發(fā)者也意識到通過new方式來生成對象占據(jù)了開發(fā)者生成對象的絕大部分,所以對于利用new操作生成對象進(jìn)行了優(yōu)化。
例如:
package com.miivii.javalib; public class Bean implements Cloneable { private String name; public Bean(String name) { this.name = name; } @Override protected Bean clone() throws CloneNotSupportedException { return (Bean) super.clone(); } } package com.miivii.javalib; public class TestClass { private static final int COUNT = 10000 * 1000; public static void main(String[] args) throws CloneNotSupportedException { long s1 = System.currentTimeMillis(); for (int i = 0; i < COUNT; i++) { Bean bean = new Bean("ylWang"); } long s2 = System.currentTimeMillis(); Bean bean = new Bean("ylWang"); for (int i = 0; i < COUNT; i++) { Bean b = bean.clone(); } long s3 = System.currentTimeMillis(); System.out.println("new = " + (s2 - s1)); System.out.println("clone = " + (s3 - s2)); } }
打印結(jié)果:
new完勝clone,真的是這樣嗎?
下面在構(gòu)造函數(shù)里做點(diǎn)簡單的事情,例如字符串截取試試。只是修改Bean,其他不變再看打印
package com.miivii.javalib; public class Bean implements Cloneable { private String name; private String firstSign;//獲取名字首字母 public Bean(String name) { this.name = name; if (name.length() != 0) { firstSign = name.substring(0, 1); firstSign += "abc"; } } @Override protected Bean clone() throws CloneNotSupportedException { return (Bean) super.clone(); } }
結(jié)論:輕量級的對象可以使用new,其他對象可以使用clone。
到此這篇關(guān)于Java 中的 clone( ) 和 new哪個(gè)效率更高的文章就介紹到這了,更多相關(guān)Java clone( ) 和 new內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis-Plus多數(shù)據(jù)源的示例代碼
本文主要介紹了MyBatis-Plus多數(shù)據(jù)源的示例代碼,包括依賴配置、數(shù)據(jù)源配置、Mapper 和 Service 的定義,具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05詳解Java程序啟動時(shí)-D指定參數(shù)是什么
java服務(wù)啟動的時(shí)候,都會指定一些參數(shù),下面這篇文章主要給大家介紹了關(guān)于Java程序啟動時(shí)-D指定參數(shù)是什么的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12RocketMq 消息重試機(jī)制及死信隊(duì)列詳解
這篇文章主要為大家介紹了RocketMq 消息重試機(jī)制及死信隊(duì)列詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10mybatisplus?復(fù)合主鍵(多主鍵)?CRUD示例詳解
這篇文章主要介紹了mybatisplus?復(fù)合主鍵(多主鍵)?CRUD實(shí)例詳解,本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03基于Spring實(shí)現(xiàn)零重啟自由編排任務(wù)的定時(shí)管理器
我們發(fā)現(xiàn),我們使用Spring自帶的定時(shí)任務(wù)如果要有修改,那么就要修改代碼,然后重啟項(xiàng)目,所以本文就帶大家實(shí)現(xiàn)一個(gè)零重啟自由編排任務(wù)的定時(shí)管理器吧2023-07-07MyBatis Plus關(guān)閉SQL日志打印的方法
這篇文章主要介紹了MyBatis-Plus如何關(guān)閉SQL日志打印,文中通過圖文結(jié)合講解的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2024-02-02