ãç¥ã£ãŠãã䟡å€ã¯ãããå€ãã®äººãç¥ããªãJavaã«é¢ããåºæ¬çãªããšããšåŒã°ããäžé£ã®ãããã¯ã®ç¶ãã åã®ãããã¯ïŒ äŸã ãã§ãªãããââã€ããªäºææ§Javaã¡ã¢ãªã¢ãã«ã¯ãJavaéçºè
ã®ã³ââãŒãã®åäœã«åœ±é¿ãäžãããã®ã§ãã ãã ãããã®éèŠãªãããã¯ã®ç¥èãç¡èŠãã人ãããªããããJMMããã€ã¹ã®æ©èœã«ãã£ãŠæ£ç¢ºã«èª¬æããããã¢ããªã±ãŒã·ã§ã³ã®å®å
šã«äºæããªãåäœã«ééããå ŽåããããŸãã ããšãã°ãäºéãã§ãã¯ããã¯ãã¿ãŒã³ã®éåžžã«äžè¬çã§
誀ã£ãå®è£
ã
èããŠã¿ãŸãããã
public class Keeper { private Data data = null; public Data getData() { if(data == null) { synchronized(this) { if(data == null) { data = new Data(); } } } return data; } }
ãã®ãããªã³ãŒããèšè¿°ãã人ã
ã¯ãå€ãæ¢ã«å²ãåœãŠãããŠããå Žåããããã¯ãåé¿ããããšã«ããããã©ãŒãã³ã¹ãæ¹åããããšããŸãã æ®å¿µãªããããããã®äººã
ã¯å€ãã®èŠå ãèæ
®ããŠããªãããããŸã³ãã®é»ç€ºé²ãçºçããå¯èœæ§ããããŸãã ã«ããã®äžã§ãç§ã¯çè«ãèªããäœããããŸããããªãå Žåã®äŸãæããŸãã ããã«ãããã€ã³ãæ ç»ã§åœŒããèšã£ãããã«ããäœãééã£ãŠããã®ããç¥ãã ãã§ã¯äžååã§ãã ãã®æ¹æ³ãç¥ã£ãŠããå¿
èŠããããŸããã ãããã£ãŠãæåã®ããã®ã¬ã·ãã¯ãããªããããã«èŠã€ããããšãã§ããŸãã
ã¡ãã£ãšããæŽå²
JMMã®æåã®ããŒãžã§ã³ã¯ã1995幎ã«Java 1.0ã§ç»å ŽããŸããã ããã¯ãäžè²«æ§ã®ããã¯ãã¹ãã©ãããã©ãŒã ã®ã¡ã¢ãªã¢ãã«ãäœæããæåã®è©Šã¿ã§ããã æ®å¿µãªããããŸãã¯å¹žããªããšã«ãããã€ãã®é倧ãªæ¬ é¥ãšèª€è§£ããããŸããã æãæ²ããåé¡ã®1ã€ã¯ãæçµãã£ãŒã«ãã®ä¿èšŒããªãããšã§ããã ã€ãŸãã1ã€ã®ã¹ã¬ãããæçµãã£ãŒã«ããæã€ãªããžã§ã¯ããäœæããå¥ã®ã¹ã¬ããããã®æçµãã£ãŒã«ãã®å€ã衚瀺ããªãå ŽåããããŸãã
java.lang.String
ã¯ã©ã¹ã§ããããã«ãããããŠããŸããã ããã«ããã®ã¢ãã«ã§ã¯ã³ã³ãã€ã©ãŒãå€ãã®å¹æçãªæé©åãè¡ãããšãã§ããªãã£ãããããã«ãã¹ã¬ããã³ãŒããèšè¿°ãããšãã«ãæåŸ
ã©ããã«æ©èœãããã©ããã確èªããããšã¯å°é£ã§ããã
ãã®ããã2004幎ã«JSR 133ãJava 5ã«ç»å Žããå
ã®ã¢ãã«ã®æ¬ ç¹ããªããªããŸããã äœãèµ·ãã£ãã®ãã«ã€ããŠè©±ããŸãã
ååæ§
å€ãã®äººããããç¥ã£ãŠããŸãããäžéšã®ãã©ãããã©ãŒã ã§ã¯èšé²æäœãéã¢ãããã¯ã«ãªãããšãããããšãæãåºãå¿
èŠããããšæããŸãã ã€ãŸããããã¹ã¬ãããå€ãèšé²ããŠããéã«ãå¥ã®ã¹ã¬ãããäœããã®äžéç¶æ
ãèŠãå ŽåããããŸãã äŸãã°ãåãlongãšdoubleã®ã¬ã³ãŒãã¯ãæ®çºæ§ãšããŠå®£èšãããŠããªãå Žåãã¢ãããã¯ã§ããå¿
èŠã¯ãªããå€ãã®ãã©ãããã©ãŒã ã§2ã€ã®æäœã§æžã蟌ãŸããŸããæäžäœããããšäžäœ32ãããã¯å¥ã
ã§ãã ïŒ
æšæºãåç
§ïŒ
å¯èŠæ§
å€ãJMMã§ã¯ãå®è¡äžã®åã¹ã¬ããã«ç¬èªã®ãã£ãã·ã¥ïŒäœæ¥ã¡ã¢ãªïŒãããããã®ã¹ã¬ãããæäœãããªããžã§ã¯ãã®ç¶æ
ãä¿åãããŠããŸããã ããã€ãã®æ¡ä»¶äžã§ã¯ããã£ãã·ã¥ã¯ã¡ã€ã³ã¡ã¢ãªãšåæããŸããããããã§ããããªãã®æéãã¡ã€ã³ã¡ã¢ãªãšãã£ãã·ã¥ã®å€ãç°ãªãå¯èœæ§ããããŸããã
æ°ããã¡ã¢ãªã¢ãã«ã§ã¯ãå€ãæ ŒçŽãããŠããæ£ç¢ºãªå Žæã«èª°ãé¢å¿ããªãããããã®ãããªæŠå¿µã¯æŸæ£ãããŸããã
å¯äžã®éèŠãªããšã¯ãããã¹ã¬ãããå¥ã®ã¹ã¬ããã«ãã£ãŠè¡ãããå€æŽãã©ã®ãããªæ¡ä»¶äžã§èŠãããšããããšã§ã ã ããã«ãããŒããŠã§ã¢ã¯æ¢ã«ãã£ãã·ã¥ãããã¬ãžã¹ã¿ã«é
眮ãããä»ã®æäœãå®è¡ããã®ã«ååãªã»ã©ã¹ããŒãã§ãã
åãC ++ãšã¯ç°ãªããã空æ°ã®å€ãã®å€ã¯æ±ºããŠåãããªãããšã«æ³šæããããšãéèŠã§ããã©ã®å€æ°ã«ã€ããŠããã¹ããªãŒã ã«ãã£ãŠç£èŠãããå€ãããã«å²ãåœãŠãããããå€ããã©ã«ãã§ã
å泚æ
ããããããã¯åœŒããèšãããã«ããã¹ãŠã§ã¯ãããŸããã
ä»ãã泚æãããšãæ瀺ãç¡æã§äº€æãããŸãïŒ ããã»ããµã¯ãåœä»€å®è¡ã®æé©åã«ãããŠéåžžã«æ©æã§ãã ã³ã³ãã€ã©ãšJITãããã«åœ¹ç«ã¡ãŸãã 泚ç®ãã¹ãå¹æã®1ã€ã¯ã1ã€ã®ã¹ã¬ããã«ãã£ãŠå®è¡ãããã¢ã¯ã·ã§ã³ãšãä»ã®ã¹ã¬ãããç°ãªãé åºã§è¡šç€ºãããããšã§ãã ãã®ãã¬ãŒãºã¯ç解ããã®ãéåžžã«é£ãããèªãã ããªã®ã§ãäŸãæããŸãã ãã®ãããªã³ãŒãããããŸãïŒ
public class ReorderingSample { boolean first = false; boolean second = false; void setValues() { first = true; second = true; } void checkValues() { while(!second); assert first; } }
ãã®ã³ãŒãã§ã¯ã
checkValues
ã¡ãœããã¯1ã€ã®ã¹ã¬ããããåŒã³åºããã
checkValues
ã¯å¥ã®ã¹ã¬ããããåŒã³åºãããŸãã
second
ãã£ãŒã«ãã¯
first
ãã£ãŒã«ããããåŸã«
true
ã«èšå®ããããããã³ãŒãã¯åé¡ãªãå®è¡ãããã¯ãã§ãããããã£ãŠãïŒããæ£ç¢ºã«ã¯ïŒ2çªç®ã®ãã£ãŒã«ããtrueã§ããããšãããããšãæåã®ãã£ãŒã«ãããã®ããã«ãªããŸãã ããããããã«ãããŸããã
ãã«ãã¹ã¬ããç°å¢ã§ã¯ãã·ã³ã°ã«ã¹ã¬ããå
ã§ãã®ããšãå¿é
ããå¿
èŠã¯ãããŸããããä»ã®ã¹ã¬ããã«ãã£ãŠå®è¡ãããæäœã®çµæã¯æ£ããé åºã§ã¯ãªãå ŽåããããŸãã æ ¹æ ããªãããã«ããã·ã³ã§ã¢ãµãŒã·ã§ã³ãæ©èœããããã£ãã®ã§ãããããŸãæåããŸããã§ããïŒ
ããããèµ·åæã«-ea
ã¹ã€ãããæå®ããããšãå¿ããŠããŸããã§ãã ïŒããããŠå¿
æ»ã«ãæªåé«ãããã©ãŒãã³ã¹ãšã³ãžãã¢ã«ããŸã é åºå€æŽãåŒãèµ·ãããŠããŸãã ããã§ãã»ã«ã²ã€ã»ã¯ã¯ã»ã³ã³ã¯ç§ã®è³ªåã«çããŸããïŒ
TSOïŒx86ãé©çšãããïŒãæèŒãããã·ã³ã§ã¯ã衚瀺ãéåžžã«å°é£ã§ã
䞊ã¹æ¿ããå£ããŸãã ããã¯ããã€ãã®ARM'eãŸãã¯
PowerPC ãŸããã¢ã«ãã¡ãåç
§ããããšãã§ããŸã-æã匱ãé åºèŠåãæã€ããã»ããµã ã¢ã«ãã¡ã¯ãã³ã³ãã€ã©ãšãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãŒãã«ã®éçºè
ã«ãšã£ãŠæªå€¢ã§ããã 圌ãæ»ãã ã®ã¯å¹žéã§ãã ãããäžã§ããã«é¢ããããããã®ç©èªãèŠã€ããããšãã§ããŸãã
å€å
žçãªäŸïŒ
ïŒäŸã¯äžèšã«äŒŒãŠããŸã-èè
ã®ã³ã¡ã³ãïŒ
... x86ã§ã¯ãåžžã«æ£ããåäœããŸãã
ãbãã«ä¿åãããšããaãã«è¡šç€ºããã³ä¿åãããŸãã
ãããŠãèšäºã§æ€èšãããŠãããã¹ãŠã®åŽé¢ã«ã€ããŠãå®éã«èµ·ãã£ãŠããããšã®å®æŒãã¢ãèŠã€ããããšèšã£ããšããã»ã«ã²ã€ã¯åã
ã§ã察å¿ããããŒããŠã§ã¢ã®ããã¥ã¢ã«ãé·ãèŠåŽããŠèªãå¿
èŠããããšèšããŸã
ãã ãã°ããã®éãé»è©±ã§å¹æãéæããããšèããŠããŸããããæçµçã«ã¯ããã»ã©éèŠã§ã¯ãªããšå€æããŸããã ããã«ãç§ã¯ãŸã ç¹å®ã®ãã©ãããã©ãŒã ã®æ©èœã«ç¹åããŠããŸããã
ãããã£ãŠãå
ã®äŸã«æ»ã£ãŠã䞊ã¹æ¿ãããããå°ç¡ãã«ããå¯èœæ§ãããããšãç解ããŠãã ããã ã³ã³ã¹ãã©ã¯ã¿ãŒã®
Data
ã¯ã©ã¹ã§ãããã»ã©éèŠã§ã¯ãªãèšç®ãå®è¡ããæãéèŠãªããšãšããŠã
éæçµãã£ãŒã«ãã«ããã€ãã®å€ãæžã蟌ã¿ãŸãã
public class Data { String question; int answer; int maxAllowedValue; public Data() { this.answer = 42; this.question = reverseEngineer(this.answer); this.maxAllowedValue = 9000; } }
data == null
ãæåã«æ€åºããã¹ã¬ããã¯æ¬¡ã®ããšãè¡ãããšã
data == null
ã
- æ°ãããªããžã§ã¯ãã«ã¡ã¢ãªãå²ãåœãŠãŸã
Data
ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒãData
Data
ã¯ã©ã¹ã®answer
ãã£ãŒã«ãã«42ãæžã蟌ã¿ãŸã- ã¯ã©ã¹
Data
question
ãã£ãŒã«ãã«ããã€ãã®è¡ãæžã蟌ã¿Data
- å€9000ã
Data
ã¯ã©ã¹ã®maxAllowedValue
ãã£ãŒã«ãã«æžã蟌ã¿ãŸã - æ°ããäœæããããªããžã§ã¯ãã
Keeper
ã¯ã©ã¹ã®data
ãã£ãŒã«ãã«æžã蟌ã¿ãŸã
ãã£ãããæããŸããïŒ ç¯3ã5ã§äœãèµ·ãã£ãã®ããèŠã
åã«ãå¥ã®ã¹ã¬ãããç¯6ã§äœãèµ·ãã£ãã®ããèŠãããšã劚ãããã®ã¯äœããããŸããã ãã®çµæããã£ãŒã«ãããŸã èšå®ãããŠããªãå Žåããã®ã¹ã¬ããã¯ãªããžã§ã¯ãã誀ã£ãç¶æ
ã§èŠãããšã«ãªããŸãã ãã¡ãããããã¯èª°ã«ãé©ããŠããªãããããªããã£ãã€ã¶ãŒ/ã³ã³ãã€ã©ãŒ/æªã®ããã«ã䞊ã¹æ¿ããå®è¡ããããšãçŠæ¢ããå³ããã«ãŒã«ããããŸãã
åã«èµ·ãã
å®çŸ©
ãããã®ã«ãŒã«ã¯ãã¹ãŠããããã
çºçåé¢ä¿ã䜿çšããŠå®çŸ©ãããŸãã 次ã®ããã«å®çŸ©ãããŸãã
ã¹ããªãŒã Xãšã¹ããªãŒã YããããšããŸãïŒå¿
ãããã¹ããªãŒã Xãšç°ãªãããã§ã¯ãããŸããïŒã ãããŠãæäœA ïŒã¹ã¬ããXã§å®è¡ïŒãšB ïŒã¹ã¬ããYã§å®è¡ïŒããããšããŸãã
ãã®å Žåã Aã¯Bã®åã«çºç ããŸããããã¯ãæäœAã®ç¬éã®åã«ã¹ã¬ããXã«ãã£ãŠè¡ããããã¹ãŠã®å€æŽãšããã®æäœã«ãã£ãŠåŒãèµ·ããããå€æŽããæäœBã®å®è¡ã®ç¬éãšãã®æäœã®å®è¡åŸã«ã¹ã¬ããYã«èŠããããšãæå³ããŸãã
èšèã§èšãã°ããã®ãããªå®çŸ©ã¯ããŸãããèªèãããªããããããªãã®ã§ãå°ã説æããŸãã ã¹ããªãŒã ã1ã€ã ãã§ãããã€ãŸã
Xãš
Yãåãã§ããæãåçŽãªã±ãŒã¹ããå§ããŸãããã ãã§ã«è¿°ã¹ãããã«ã1ã€ã®ã¹ã¬ããå
ã§ã¯ããœãŒã¹ã³ãŒãã§ç€ºãããŠããé åºïŒããã°ã©ã ã®é åºïŒã«åŸã£ãŠæäœãçžäºã«é¢é£ããŠçºçãããããåé¡ã¯ãããŸããã ãã«ãã¹ã¬ããã®å Žåããã¹ãŠãããè€éã«ãªããŸãããããã§ã¯...ç»åãç解ã§ããŸããã ãããŠããã«åœŒå¥³ã¯ïŒ
ããã§ã¯ãå·ŠåŽã§ãã¹ããªãŒã Yã衚瀺ãããããšãä¿èšŒãããŠããæäœãç·è²ã§ããŒã¯ããã衚瀺ãããªãå¯èœæ§ãããæäœãèµ€è²ã§ããŒã¯ãããŠããŸãã å³åŽã§ã¯ããããã®æäœã¯èµ€ã§ããŒã¯ããããã®å®è¡äžãå·Šã®ç·ã®æäœã®çµæã¯ãŸã 衚瀺ãããªãå Žåããããç·ã§ã¯ãã¹ãŠã衚瀺ãããå ŽåããããŸãã happen-beforeé¢ä¿ã¯
æšç§»çã§ããããšã«æ³šæããããšãéèŠã§ããã€ãŸããA
ã B
ã®åã«çºçã ãB
ã Cã®
åã«çºçãã
å Žå ãA
㯠Cã®
åã«çºçããŸã ã
çºçåã®é¢ä¿ã«é¢é£ããæäœ
次ã«ãJMMã§ã®äžŠã¹æ¿ãã®å¶éäºé
ãæ£ç¢ºã«èŠãŠã¿ãŸãããã æ·±ã詳现ãªèª¬æã¯ãäŸãã°
The JSR-133 Cookbookã«ãããŸãããç§ã¯ãã¹ãŠãå°ãè¡šé¢çãªã¬ãã«ã«ããããããããã€ãã®å¶éãèŠéããŸãã æãåçŽã§æãæåãªããã¯ããå§ããŸãããã
1.ã¢ãã¿ãŒã®è§£æŸã¯
ãåãã¢ãã¿ãŒãååŸ
ãã åã«çºçããŸãã 泚ïŒåºå£ã§ã¯ãªããªãªãŒã¹ã§ããã€ãŸãã
wait
ã䜿çšããå Žåãã»ãã¥ãªãã£ã«ã€ããŠå¿é
ããå¿
èŠã¯ãããŸããã
ãã®ç¥èãç§ãã¡ã®äŸãä¿®æ£ããã®ã«ã©ã®ããã«åœ¹ç«ã€ãèŠãŠã¿ãŸãããã ãã®å Žåããã¹ãŠãéåžžã«ç°¡åã§ããå€éšãã§ãã¯ãåé€ããåæããã®ãŸãŸã«ããŠãããŸãã ããã§ã2çªç®ã®ã¹ã¬ããã¯ãä»ã®ã¹ã¬ãããã¢ãã¿ãŒã解æŸããåŸã«ã®ã¿ã¢ãã¿ãŒãåãåãããããã¹ãŠã®å€æŽã確èªããããšãä¿èšŒãããŸãã ãããŠã圌ã¯ãã¹ãŠãåæåããããŸã§åœŒãææŸããªãã®ã§ãåå¥ã«ã§ã¯ãªãããã¹ãŠã®å€æŽãäžåºŠã«èŠãããšãã§ããŸãïŒ
public class Keeper { private Data data = null; public Data getData() { synchronized(this) { if(data == null) { data = new Data(); } } return data; } }
2. volatileå€æ°ãžã®æžã蟌ã¿ã¯ãåãå€æ°ããèªã¿åã
åã«è¡ãããŸãã
ãã¡ãããç§ãã¡ãè¡ã£ãå€æŽã¯äžæ£ç¢ºããä¿®æ£ããŸãããå
ã®ã³ãŒããæžãã人ãå
ã®ã³ãŒã-æ¯åããã¯ã«æ»ããŸãã volatileããŒã¯ãŒãã¯ä¿åã§ããŸãã å®éãæ€èšäžã®ã¹ããŒãã¡ã³ãïŒ2ïŒã¯ãvolatileãšå®£èšããããã¹ãŠãèªã¿åããšãã«ãåžžã«çŸåšã®å€ãååŸããããšãæå³ããŸãã ããã«ãåè¿°ããããã«ãæ®çºæ§ãã£ãŒã«ãã®å Žåãæžã蟌ã¿ã¯åžžã«ïŒlongããã³doubleãå«ãïŒã¢ãããã¯æäœã§ãã å¥ã®éèŠãªç¹ïŒä»ã®ãšã³ãã£ãã£ïŒããšãã°ãé
åããªã¹ãããŸãã¯ä»ã®ã¯ã©ã¹ïŒãžã®åç
§ãæã€æ®çºæ§ãšã³ãã£ãã£ãããå Žåããã¹ãŠã§ã¯ãªãããšã³ãã£ãã£èªäœãžã®åç
§ã®ã¿ãåžžã«ãæ°é®®ãã«ãªããŸãçä¿¡ã
ããã§ã¯ãããã«ããã¯ã©ã ã«æ»ããŸãããã volatileã䜿çšãããšã次ã®ãããªç¶æ³ãä¿®æ£ã§ããŸãã
public class Keeper { private volatile Data data = null; public Data getData() { if(data == null) { synchronized(this) { if(data == null) { data = new Data(); } } } return data; } }
ããã§ã¯ãŸã
data == null
å Žåã«ã®ã¿ããã¯ããã
data == null
ã æ®ãã®ã±ãŒã¹ã§ã¯ãvolatileèªã¿åãã䜿çšããŠé€å€ããŸãã æ®çºæ§ã¹ãã¢
ãæ®çºæ§èªã¿åãã®
åã«çºçããã³ã³ã¹ãã©ã¯ã¿ãŒã§çºçãããã¹ãŠã®æäœããã£ãŒã«ãã®å€ãèªã¿åããŠãŒã¶ãŒã«è¡šç€ºããããšããäºå®ã«ãã£ãŠãæ£ç¢ºããä¿èšŒãããŸãã
ããã«ãããã§ã¯èå³æ·±ãä»®å®ã䜿çšãããŠããã確èªãã䟡å€ããããŸããæ®çºæ§ã¹ãã¢+èªã¿åãã¯ããã¯ãããé«éã§ãã ãã ããåãããã©ãŒãã³ã¹ãšã³ãžãã¢ã絶ãéãªãç§ãã¡ã«ç¹°ãè¿ããŠããããã«ããã€ã¯ããã³ãããŒã¯ã¯çŸå®ãšã¯ã»ãšãã©é¢ä¿ããããŸãããç¹ã«ã枬å®ããããšããŠããä»çµã¿ãããããªãå Žåã¯ããã§ãã ããã«ãããªãããããã©ã®ããã«æ©èœããããç¥ã£ãŠãããšæããªããããªãã¯ééãã§ããå¯èœæ§ãé«ããéèŠãªèŠçŽ ãèæ
®ã«å
¥ããŠããŸããã ãã³ãããŒã¯ãäœæããããã®ç¥èã®æ·±ãã«ã¯ååãªèªä¿¡ããªãã®ã§ãããã§ã¯ãã®ãããªæž¬å®å€ã¯ãããŸããã ãã ãããã®
ãã¬ãŒã³ããŒã·ã§ã³ã«ã¯ ãã¹ã©ã€ãïŒ54ããå§ãŸãæ®çºæ§ã®ããã©ãŒãã³ã¹ã«é¢ããæ
å ±ããããŸãïŒãã ãããã¹ãŠãèªãããšã匷ããå§ãããŸãïŒã
UPDïŒèšèšäžãvolatileãããvolatileãããã¯ããã«éããšããèå³æ·±ã
ã³ã¡ã³ãããããŸãã
3. final
ãã£ãŒã«ãã«å€ãæžã蟌ãïŒããã³ããã®ãã£ãŒã«ãããªã³ã¯ã®å Žåããã®ãã£ãŒã«ãããå°éå¯èœãªãã¹ãŠã®å€æ°ïŒåç
§ãã§ãŒã³ïŒïŒã
çºçåãªããžã§ã¯ãã®äœææã«ãå€éšã§çºçããå€æ°ã«ãã®ãªããžã§ã¯ããæžã蟌ããã®ã³ã³ã¹ãã©ã¯ã¿ã
ãããããªããããã«ããã§ãããæ¬è³ªã¯åçŽã§ãïŒ
final
ãã£ãŒã«ããæã€ãªããžã§ã¯ããããå Žåããã®ãªããžã§ã¯ãã¯ãã®
final
ãã£ãŒã«ãïŒããã³ãã®ãã£ãŒã«ããåç
§ã§ãããã¹ãŠïŒãèšå®ããåŸã«ã®ã¿äœ¿çšã§ããŸãã ãã ããã³ã³ã¹ãã©ã¯ã¿ãŒããå€éšã®æ§ç¯ããããªããžã§ã¯ãïŒã€ãŸã
this
ïŒãžã®ãªã³ã¯ãæž¡ããšã誰ããããªãã®ãªããžã§ã¯ããæªå®æã®ç¶æ
ã§èŠãå¯èœæ§ãããããšãå¿ããªãã§ãã ããã
ãã®äŸã§ã¯ããã£ãŒã«ããæåŸã®ã¬ã³ãŒãã
final
ãäœæããã ãã§ååã§ããããšãããããŸãã
public class Data { String question; int answer; final int maxAllowedValue; public Data() { this.answer = 42; this.question = reverseEngineer(this.answer); this.maxAllowedValue = 9000; } private String reverseEngineer(int answer) { return null; } }
å¯äžã®ãã€ã³ãã¯ãéæ³ã®ããã«æ©èœããããšã§ãããããªãã®ç¬åµçãªã¬ã»ãã·ã§ã³ãç¥ããªã人ã¯ããªããç解ã§ããªããããããŸããã ã¯ããããªãããããããã«å¿ããããšãã§ããŸãã ãã¡ãããããã§äœãèµ·ãã£ãŠããã®ãã説æããããã£ã¡ã®ããªãã¯ïŒããªã©ã®èªãããã³ã¡ã³ããè¿œå ãããªãã·ã§ã³ããããŸãããäœããã®çç±ã§ããã¯ããŸãè¯ãç¿æ
£ã§ã¯ãªãããã§ãã
UPDïŒããã¯äºå®ã§ã¯ãããŸããã ã³ã¡ã³ãã¯
çç±ã説æ
ããŸãã
UPD2 ïŒåé¡ã®è°è«ã«ç¶ããŠãRuslanã¯
èšäºãæžããŸã
ã ã
ããã«ããã£ãŒã«ããéçã§ãããJVMã¯ã©ã¹ã¯æåã®åŒã³åºãã§1åã ãåæåãå®è¡ããããšãä¿èšŒãããŠããããšãèŠããŠããããšãéèŠã§ãã ãã®å Žåãåãã·ã³ã°ã«ãã³ïŒ
ãã®èšäºã®ãã¬ãŒã ã¯ãŒã¯å
ã§ãã¿ãŒã³ãŸãã¯ã¢ã³ããã¿ãŒã³ãšãåŒã°ããŸããããã®èšäºã§ã¯ãŸã£ãã説æããŸããã ïŒã次ã®ããã«å®è£
ã§ããŸãã
public class Singleton { private Singleton() {} private static class InstanceContainer { private static final Singleton instance = new Singleton(); } public Singleton getInstance() { return InstanceContainer.instance; } }
ãã¡ãããããã¯ã·ã³ã°ã«ãã³ãå®è£
ããæ¹æ³ã«ã€ããŠã®ã¢ããã€ã¹ã§ã¯ãããŸãããEffectiveJavaãèªã人ã¯èª°ã§ã
ãäœããã®çç±ã§çªç¶äœããã®çç±ã§ãããæžãããšã«æ±ºããå Žåãenumã䜿çšãããã«ãã¹ã¬ãããã·ãªã¢ã«åãããã³ã¯ããŒãã³ã°ã«é¢ãããã¹ãŠã®åé¡ã®è§£æ±ºçã瀺ããŠããŸãã
UPDïŒã·ã³ã°ã«ãã³ã®æé©ãªå®è£
æ¹æ³ã«ã€ããŠã¯ã
ãã®ãããã¯ãåç
§ããŠãã ããã
ãšããã§ãReflectionã䜿çšããŠæçµãã£ãŒã«ããå€æŽã§ããããšãç¥ã£ãŠãã人ãããã³ãã®ãããªå€æŽãã©ã®ããã«è¡šç€ºããããã«èå³ããã人ã«ãšã£ãŠãç§ã¯ããèšãããšãã§ããŸããããã¹ãŠãããŸãããããã«èŠããŸãããªããããã¹ãŠãæ¬åœã«ãããã©ããã¯äžæã§ããããã§ããã ãã®ãããã¯ã«ã¯ããã€ãã®ãããã¯ããããŸãããããã¯æãã€ã³ã¿ãŒã³ã§ãã ã³ã¡ã³ãã§èª°ãããããå®éã«ã©ã®ããã«ãªã£ãŠããã®ããæããŠããããªããç§ã¯éåžžã«å¹žãã§ãã ãããã誰ãèšããªãå Žåãç§èªèº«ãèŠã€ããŠã確å®ã«äŒããã§ãããã
UPD ïŒåœŒãã¯ã³ã¡ã³ãã§
èšã£ãã
確ãã«ããã®èšäºã§ã¯åãäžããªãã£ãçºçåã®é¢ä¿ã«é¢é£ããä»ã®æäœãããã€ããããŸããããããã¯æ¢ã«ããå
·äœçã§ãããèå³ãããå Žåã¯ã
æšæºãŸãã¯ä»ã®å Žæã§èªåèªèº«ãèŠã€ããŠå
±æããããšãã§ããŸãã³ã¡ã³ãã®å
šå¡ã
ã¯ã¬ãžããããªã³ã¯ãããã³ãã®
ãŸããåè¿°ã®ããã©ãŒãã³ã¹ãšã³ãžãã¢ã§ãã
Alexei TheShade Shipilevãš
Sergey Walrus Kuksenkoã®èšåºçãªãã³ã»ã³ã¹ã®å
容ã«é¢ããèšäºã®ããã€ãã®åè°ãšäºåæ€èšŒã«æè¬ããŸãã
ãŸããèšäºã®å·çæã«äœ¿çšãããœãŒã¹ã®ãªã¹ããšããããã¯ã«é¢ããé©åãªãªã³ã¯ã瀺ããŸãã
ã³ã¡ã³ãã«èå³æ·±ã質åãè¿œå ãä¿®æ£ãæ®ããŠãã ãããèªãã§çããŠããããã§ãã