找工作難吶大家好,我原本是神劍山莊的鑄劍師,名叫小趙,本來干的好好的,后來一時(shí)興起,睡了三少爺?shù)男∫套?,與其一直提心吊膽,干脆來個(gè)逃之夭夭。 但是,我也要吃飯的呀,工作也得找,神劍山莊去不得,還有斷劍山莊、藏劍山莊、蕩劍山莊、等等等等大型企業(yè),說不定這次跳槽,能跳出個(gè)飛黃騰達(dá)! 為了提高我投簡歷的準(zhǔn)確性,我覺得簡歷要寫的多樣化,不能全寫一模一樣,比如說我的期望薪資不能寫成一樣,因?yàn)槲蚁M軌蚋鶕?jù)目標(biāo)企業(yè)的情況來投遞合適薪資的簡歷,這樣中標(biāo)概率大一點(diǎn)。
這是我的簡歷類: public class Resume { private String name; private String position; private int salary; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPosition() { return position; } public void setPosition(String position) { this.position = position; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } @Override public String toString() { return "Resume{" + "name='" + name + '\'' + ", position='" + position + '\'' + ", salary=" + salary + '}'; } }
現(xiàn)在,我正在熬夜寫簡歷。。。。。 public static void main(String[] args) { Resume resume1 = new Resume(); resume1.setName("小趙"); resume1.setPosition("高級鑄劍工程師"); resume1.setSalary(1000); Resume resume2 = new Resume(); resume2.setName("小趙"); resume2.setPosition("高級鑄劍工程師"); resume2.setSalary(1200); Resume resume3 = new Resume(); resume2.setName("小趙"); resume3.setPosition("高級鑄劍工程師"); resume3.setSalary(1500); //..... } 當(dāng)我寫到20多份的時(shí)候,我已經(jīng)睡著了。。。。。 唉,找工作難啊。。。。。。
打印機(jī)跑起來第二天,我去萬達(dá)廣場買了個(gè)打印機(jī)回來,直接循環(huán)打?。?/p> public static void main(String[] args) { int num = 5; while (num > 0){ Resume resume1 = new Resume(); int salary = (int)(1000+Math.random()*(2000-1000+1)); resume1.setName("小趙"); resume1.setPosition("高級鑄劍工程師"); resume1.setSalary(salary); System.out.println(resume1.toString()); num --; } } 輸出: Resume{name='小趙', position='高級鑄劍工程師', salary=1389}
先試了一下,打印5份簡歷,感覺沒問題。 有了這個(gè)打印機(jī)之后,我也接些私活,幫別人打印簡歷,生意越做越火,一個(gè)月后,我工作沒找到,但打印機(jī)一天到晚倒是沒停過。 到了現(xiàn)在,我的打印機(jī)一天到晚要打印一百萬張簡歷,每次打印都要耗電耗內(nèi)存耗機(jī)器壽命,我的打印機(jī)已經(jīng)報(bào)廢了好幾臺,并且在不斷的購買新的打印機(jī)。 作為一個(gè)工程師,我決定要研究一下有沒有更好的解決辦法。
復(fù)印機(jī)跑起來聽說Cloneable接口有個(gè)復(fù)印機(jī)可以用,我決定去試試,效果的好的話就把復(fù)印機(jī)裝到打印機(jī)里面去,搞個(gè)多功能一體機(jī)。 這是修改后的簡歷類: public class Resume implements Cloneable{ private String name; private String position; private int salary; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPosition() { return position; } public void setPosition(String position) { this.position = position; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } @Override protected Resume clone(){ Resume resume = null; try{ resume = (Resume) super.clone(); }catch (CloneNotSupportedException e){ e.printStackTrace(); } return resume; } @Override public String toString() { return "Resume{" + "name='" + name + '\'' + ", position='" + position + '\'' + ", salary=" + salary + '}'; } }
復(fù)印機(jī)跑起來: public static void main(String[] args) { int num = 5; Resume resume = new Resume(); while (num > 0){ Resume resume1 = resume.clone(); int salary = (int)(1000+Math.random()*(2000-1000+1)); resume1.setName("小趙"); resume1.setPosition("高級鑄劍工程師"); resume1.setSalary(salary); System.out.println(resume1.toString()); num --; } } 和打印機(jī)的效果是一樣的,但是這里事實(shí)上只打印了一次,然后其他的都是拷貝復(fù)印出來的。 。。。。。。 多年之后,我才恍然大悟,當(dāng)初我用復(fù)印機(jī)復(fù)印簡歷的做法,其實(shí)就是設(shè)計(jì)模式中的原型模式。 原型模式的使用場景大體上有兩種使用場景 1.在需要一個(gè)類的大量對象的時(shí)候,使用原型模式是最佳選擇,因?yàn)樵湍J绞窃趦?nèi)存中對這個(gè)對象進(jìn)行拷貝,要比直接new這個(gè)對象性能要好很多,在這種情況下,需要的對象越多,原型模式體現(xiàn)出的優(yōu)點(diǎn)越明顯。 2.如果一個(gè)對象的初始化需要很多其他對象的數(shù)據(jù)準(zhǔn)備或其他資源的繁瑣計(jì)算,那么可以使用原型模式。 3.當(dāng)需要一個(gè)對象的大量公共信息,少量字段進(jìn)行個(gè)性化設(shè)置的時(shí)候,也可以使用原型模式拷貝出現(xiàn)有對象的副本進(jìn)行加工處理。
構(gòu)造函數(shù)的問題寫個(gè)程序測一下構(gòu)造函數(shù): public class AAA implements Cloneable { public AAA() { System.out.println("我來了。。"); } @Override protected AAA clone(){ AAA aaa = null; try { aaa = (AAA) super.clone(); }catch (CloneNotSupportedException e){ e.printStackTrace(); } return aaa; } } public static void main(String[] args) { AAA aaa = new AAA(); AAA aaa1 = aaa.clone(); } 輸出: 我來了。。 就輸出一次,這里可以證明對象拷貝的時(shí)候構(gòu)造函數(shù)是不會執(zhí)行的,原因在于拷貝是直接在堆中進(jìn)行,這其實(shí)也可以理解,new的時(shí)候,JVM要走一趟類加載流程,這個(gè)流程非常麻煩,在類加載流程中會調(diào)用構(gòu)造函數(shù),最后生成的對象會放到堆中,而拷貝就是直接拷貝堆中的現(xiàn)成的二進(jìn)制對象,然后重新一個(gè)分配內(nèi)存塊。
淺拷貝上個(gè)例子展示什么是淺拷貝 這里新加一個(gè)類BBB: public class BBB{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
AAA類修改為: public class AAA implements Cloneable { private BBB bbb = new BBB(); public void setName(String name) { this.bbb.setName(name); } public String getName() { return this.bbb.getName(); } @Override protected AAA clone(){ AAA aaa = null; try { aaa = (AAA) super.clone(); }catch (CloneNotSupportedException e){ e.printStackTrace(); } return aaa; } }
main方法: public static void main(String[] args) { AAA aaa = new AAA(); aaa.setName("張三"); System.out.println(aaa.getName()); AAA aaa1 = aaa.clone(); System.out.println(aaa1.getName()); } 輸出: 張三 這種情況就是淺拷貝,java只拷貝你指定的對象,至于你指定的對象里面的別的對象,它不拷貝,還是把引用給你,共享變量,這是一種非常不安全的方式,需要特別注意。 內(nèi)部的數(shù)組和引用對象不會拷貝,其他的原始基本類型和String類型會被拷貝。
如果要實(shí)現(xiàn)深拷貝呢? 那就只能在AAA的clone方法里把BBB實(shí)例化出來了: @Override protected AAA clone(){ AAA aaa = null; try { aaa = (AAA) super.clone(); aaa.bbb = new BBB(); }catch (CloneNotSupportedException e){ e.printStackTrace(); } return aaa; }
|
|