éçã³ãŒã ã¢ãã©ã€ã¶ãŒã¯ãäžæ³šæã«ãã£ãŠçºçãããšã©ãŒãçºèŠããã®ã«åœ¹ç«ã€ããã人æ°ããããŸããããããããã«èå³æ·±ãã®ã¯ãç¡ç¥ããçããééããä¿®æ£ããã®ã«åœ¹ç«ã€ããšã§ããããšããã®èšèªã®å
¬åŒããã¥ã¡ã³ãã«ãã¹ãŠãæžãããŠãããšããŠãããã¹ãŠã®ããã°ã©ããŒãããã泚ææ·±ãèªãã ãšããäºå®ã¯ãããŸããããããŠãããã°ã©ããªãç解ã§ãããšæããŸããããã¹ãŠã®ããã¥ã¡ã³ããèªãã®ã¯ããããããã§ãããããã®ç¹ã«ãããŠãéçã¢ãã©ã€ã¶ãŒã¯ãããªãã®é£ã«åº§ã£ãŠã³ãŒããæžãã®ãèŠå®ã£ãŠãããçµéšè±å¯ãªå人ã®ãããªãã®ã§ãã圌ã¯ããããã¯ã³ããŒããŠè²Œãä»ãããšãã«ééããå Žæã§ãããšèšãã ãã§ãªããããããããã®ããã«æžãããšã¯ã§ããŸãããèªåã§ããã¥ã¡ã³ããèŠãŠãã ãããããšãèšããŸãããã®ãããªå人ã¯ãããã¥ã¡ã³ãèªäœããã圹ã«ç«ã¡ãŸãããªããªãã圌ã¯ä»äºã§å®éã«ééããäºæã ããææ¡ããããªãã«ãšã£ãŠæ±ºããŠåœ¹ã«ç«ããªãäºæã«ã€ããŠã¯æ²é»ããããã§ãããã®æçš¿ã§ã¯ãFindBugs éçã¢ãã©ã€ã¶ãŒã®äœ¿çšããåŠãã Java ã®è€éãã®ããã€ãã«ã€ããŠèª¬æããŸãããããããããªãã«ãšã£ãŠãäºæ³å€ã®ããšãèµ·ãããããããŸããããã¹ãŠã®äŸãæšæž¬çãªãã®ã§ã¯ãªããå®éã®ã³ãŒãã«åºã¥ããŠããããšãéèŠã§ãã
äžé æŒç®å ?:
äžé æŒç®åã»ã©åçŽãªãã®ã¯ãªãããã«æããŸãããããã«ã¯èœãšãç©ŽããããŸããã©ã¡ãã®ãã¶ã€ã³ã«ãåºæ¬çãªéãã¯ãªããšä¿¡ããŠããŸãããType var = condition ? valTrue : valFalse;
ã Type var; if(condition) var = valTrue; else var = valFalse;
ããã«åŸ®åŠãªç¹ãããããšãåãããŸãããäžé
æŒç®åã¯è€éãªåŒã®äžéšã§ããå¯èœæ§ãããããããã®çµæã¯ã³ã³ãã€ã«æã«æ±ºå®ãããå
·è±¡åã§ããå¿
èŠããããŸãããããã£ãŠãããšãã°ãif 圢åŒã§ true æ¡ä»¶ãæå®ãããšãã³ã³ãã€ã©ã¯ valTrue ã Type ã«çŽæ¥å°ããäžé
æŒç®åã®åœ¢åŒã§ããŸãå
±éã®å valTrue ãš valFalse ã«å°ããŸã (valFalse ã¯ããã§ãªãã«ãããããã)ãè©äŸ¡ãããŸã)ããã®çµæã¯ã¿ã€ã Type ã«ã€ãªãããŸããåŒã«ããªããã£ãåãšãã®ã©ãã㌠(IntegerãDouble ãªã©) ãå«ãŸããå Žåããã£ã¹ã ã«ãŒã«ã¯å®å
šã«èªæã§ã¯ãããŸããããã¹ãŠã®ã«ãŒã«ã¯ JLS 15.25 ã§è©³ãã説æãããŠããŸããããã€ãã®äŸãèŠãŠã¿ãŸãããã Number n = flag ? new Integer(1) : new Double(2.0);
ãã©ã°ãèšå®ãããŠããå Žåãn ã¯ã©ããªããŸãã? å€ã 1.0 ã® Double ãªããžã§ã¯ããã³ã³ãã€ã©ã¯ããªããžã§ã¯ããäœæãããšããäžåšçšãªè©Šã¿ãé¢çœããšå€æããŸãã2 çªç®ãš 3 çªç®ã®åŒæ°ã¯ç°ãªãããªããã£ãåã®ã©ãããŒã§ãããããã³ã³ãã€ã©ã¯ããããã¢ã³ã©ããããããæ£ç¢ºãªå (ãã®å Žå㯠double) ãçæããŸãããããŠã代å
¥ã«å¯ŸããŠäžé
æŒç®åãå®è¡ããåŸãå床ããã¯ã¹åãè¡ãããŸããæ¬è³ªçã«ããã®ã³ãŒãã¯æ¬¡ãšåçã§ãã Number n; if( flag ) n = Double.valueOf((double) ( new Integer(1).intValue() )); else n = Double.valueOf(new Double(2.0).doubleValue());
ã³ã³ãã€ã©ã®èŠ³ç¹ããã¯ãã³ãŒãã«ã¯åé¡ã¯ãªããå®å
šã«ã³ã³ãã€ã«ãããŸããããããFindBugs ã¯æ¬¡ã®ããã«èŠåããŸãã
BX_UNBOXED_AND_COERCED_FOR_TERNARY_OPERATOR: TestTernary.main(String[]) ã®ããªããã£ãå€ãããã¯ã¹å解é€ãããäžé æŒç®åã«å¯ŸããŠåŒ·å¶ãããŸãã ã©ãããããããªããã£ãå€ãããã¯ã¹å解é€ãããæ¡ä»¶ä»ãäžé æŒç®å (b? e1: e2 æŒç®å) ã®è©äŸ¡ã®äžéšãšããŠå¥ã®ããªããã£ãåã«å€æãããŸãã ïŒãJava ã®ã»ãã³ãã£ã¯ã¹ã§ã¯ãe1 ãš e2 ãã©ãããããæ°å€ã®å Žåãå€ã¯ããã¯ã¹åãããŠããªãç¶æ ã§å ±éã®åã«å€æ/匷å¶ãããããšã矩åä»ããããŠããŸã (ããšãã°ãe1 ã Integer åã§ãe2 ã Float åã§ããå Žåãe1 ã¯ããã¯ã¹åãããŠããŸãããæµ®åå°æ°ç¹å€ã«å€æãããããã¯ã¹åãããŸããJLS ã»ã¯ã·ã§ã³ 15.25 ãåç §ããŠãã ããããã¡ãããFindBugs ã¯ãInteger.valueOf(1) ã new Integer(1) ãããå¹ççã§ããããšãèŠåããŸãããããã¯èª°ãããã§ã«ç¥ã£ãŠããŸãããŸãã¯æ¬¡ã®äŸ:
Integer n = flag ? 1 : null;
ãã©ã°ãèšå®ãããŠããªãå Žåãäœæè
㯠n ã« null ãå
¥ããããšèããŠããŸããããŸããããšæããŸããïŒã¯ããããããäºæ
ãè€éã«ããŸãããã Integer n = flag1 ? 1 : flag2 ? 2 : null;
倧ããªéãã¯ãªãããã§ãããã ããäž¡æ¹ã®ãã©ã°ãã¯ãªã¢ãããŠããå Žåããã®è¡ã¯ NullPointerException ãã¹ããŒããŸããå³åŽã®äžé
æŒç®åã®ãªãã·ã§ã³ã¯ int ãš null ã§ãããããçµæã®å㯠Integer ã«ãªããŸããå·ŠåŽã®ãªãã·ã§ã³ã¯ int ãš Integer ã§ãããããJava ã«ãŒã«ã«åŸã£ãŠçµæ㯠int ã«ãªããŸãããããè¡ãã«ã¯ãäŸå€ãã¹ããŒãã intValue ãåŒã³åºããŠããã¯ã¹å解é€ãå®è¡ããå¿
èŠããããŸããã³ãŒãã¯ãããšåçã§ãã Integer n; if( flag1 ) n = Integer.valueOf(1); else { if( flag2 ) n = Integer.valueOf(Integer.valueOf(2).intValue()); else n = Integer.valueOf(((Integer)null).intValue()); }
ããã§ãFindBugs ã¯ãšã©ãŒãçãã®ã«åå㪠2 ã€ã®ã¡ãã»ãŒãžãçæããŸãã
BX_UNBOXING_IMMEDIATELY_REBOXED: ããã¯ã¹åãããå€ãããã¯ã¹å解é€ãããTestTernary.main(String[]) ã§ããã«åããã¯ã¹åãããŸãã NP_NULL_ON_SOME_PATH: TestTernary.main(String[]) 㧠null ã® null ãã€ã³ã¿ãŒéåç §ãçºçããå¯èœæ§ããããŸãã å®è¡ãããšã null å€ã¯éåç §ããããããã³ãŒãã®å®è¡æã« NullPointerException ãçæãããŸããããŠããã®ãããã¯ã«é¢ããæåŸã®äŸã§ãã
double[] vals = new double[] {1.0, 2.0, 3.0}; double getVal(int idx) { return (idx < 0 || idx >= vals.length) ? null : vals[idx]; }
ãã®ã³ãŒããæ©èœããªãã®ã¯é©ãã¹ãããšã§ã¯ãããŸãããããªããã£ãåãè¿ãé¢æ°ã¯ã©ã®ããã«ã㊠null ãè¿ãã®ã§ãããã? é©ããããšã«ãåé¡ãªãã³ã³ãã€ã«ã§ããŸããããã§ãããã³ã³ãã€ã«ãå®äºããçç±ã¯ãã§ã«ç解ã§ããŸããã
æ¥ä»åœ¢åŒ
Java ã§æ¥ä»ãšæå»ããã©ãŒãããããã«ã¯ãDateFormat ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããã¯ã©ã¹ã䜿çšããããšããå§ãããŸããããšãã°ã次ã®ããã«ãªããŸããpublic String getDate() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); }
å€ãã®å Žåãã¯ã©ã¹ã¯åã圢åŒãç¹°ãè¿ã䜿çšããŸããå€ãã®äººã¯æé©åãšããã¢ã€ãã¢ãæãã€ãã§ããããå
±éã®ã€ã³ã¹ã¿ã³ã¹ã䜿çšã§ããã®ã«ããªãæ¯åãã©ãŒããã ãªããžã§ã¯ããäœæããã®ã§ãããã? private static final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public String getDate() { return format.format(new Date()); }
ãšãŠãçŸãããŠã¯ãŒã«ã§ãããæ®å¿µãªããæ©èœããŸãããããæ£ç¢ºã«èšãã°ãåäœããŸãããæã
å£ããŸããå®éãDateFormat ã®ããã¥ã¡ã³ãã«ã¯æ¬¡ã®ããã«æžãããŠããŸãã
æ¥ä»åœ¢åŒã¯åæãããŸãããã¹ã¬ããããšã«åå¥ã®åœ¢åŒã€ã³ã¹ã¿ã³ã¹ãäœæããããšããå§ãããŸããè€æ°ã®ã¹ã¬ãããåæã«ãã©ãŒãããã«ã¢ã¯ã»ã¹ããå Žåã¯ãå€éšã§åæããå¿ èŠããããŸããããã¯ãSimpleDateFormat ã®å éšå®è£ ãèŠããšåœãŠã¯ãŸããŸããformat() ã¡ãœããã®å®è¡äžããªããžã§ã¯ãã¯ã¯ã©ã¹ ãã£ãŒã«ãã«æžã蟌ãããã2 ã€ã®ã¹ã¬ãããã SimpleDateFormat ãåæã«äœ¿çšãããšãäžå®ã®ç¢ºçã§äžæ£ãªçµæãçºçããŸããããã«ã€ã㊠FindBugs ã¯æ¬¡ã®ããã«æžããŠããŸãã
STCAL_INVOKE_ON_STATIC_DATE_FORMAT_INSTANCE: TestDate.getDate() ã®éç java.text.DateFormat ã¡ãœããã®åŒã³åºã JavaDoc ã«èšèŒãããŠããããã«ãDateFormat ã¯æ¬è³ªçã«ãã«ãã¹ã¬ããã§ã®äœ¿çšã«ã¯å®å šã§ã¯ãããŸãããæ€åºåšã¯ãéçãã£ãŒã«ããä»ããŠååŸããã DateFormat ã®ã€ã³ã¹ã¿ã³ã¹ãžã®åŒã³åºããæ€åºããŸãããããã¯çãããããã§ãã詳现ã«ã€ããŠã¯ãSun Bug #6231579 ããã³ Sun Bug #6178997 ãåç §ããŠãã ããã
BigDecimal ã®èœãšãç©Ž
BigDecimal ã¯ã©ã¹ã䜿çšãããšä»»æã®ç²ŸåºŠã®å°æ°ãæ ŒçŽã§ããããšãåŠã³ãããã« double ã®ã³ã³ã¹ãã©ã¯ã¿ãŒãããããšãèŠãŠããã¹ãŠãæ確ã§ããã次ã®ããã«å®è¡ã§ãããšå€æãã人ãããŸãã System.out.println(new BigDecimal( 1.1)); ãããå®éã«çŠæ¢ããŠãã人ã¯ããŸããããçµæã¯äºæãã¬ããã«èŠãããããããŸãã: 1.100000000000000088817841970012523233890533447265625ãããã¯ãåå§ double ã IEEE754 圢åŒã§æ ŒçŽãããŠããããã«çºçããŸããIEEE754 圢åŒã§ã¯ã1.1 ãå®å šã«æ£ç¢ºã«è¡šãããšã¯äžå¯èœã§ã (2 é²æ°ç³»ã§ã¯ãç¡éã®åšæåæ°ãåŸãããŸã)ããããã£ãŠã1.1 ã«æãè¿ãå€ãããã«æ ŒçŽãããŸããããã©ããããBigDecimal(double) ã³ã³ã¹ãã©ã¯ã¿ãŒã¯æ£ç¢ºã«æ©èœããŸããIEEE754 ã®æå®ãããæ°å€ã 10 é²æ°åœ¢åŒã«å®å šã«å€æããŸã (æåŸã® 2 é²æ°ã®å°æ°éšã¯ãåžžã«æåŸã® 10 é²æ°ãšããŠè¡šçŸã§ããŸã)ãBigDecimal ãšã㊠1.1 ãæ£ç¢ºã«è¡šãããå Žåã¯ãnew BigDecimal("1.1") ãŸã㯠BigDecimal.valueOf(1.1) ãèšè¿°ã§ããŸããçªå·ãããã«è¡šç€ºããã«ãããã䜿çšããŠäœããã®æäœãè¡ããšããšã©ãŒã®åå ãããããªãå¯èœæ§ããããŸããFindBugs ã¯ãåãã¢ããã€ã¹ãäžããèŠå DMI_BIGDECIMAL_CONSTRUCTED_FROM_DOUBLE ãçºè¡ããŸãããã 1 ã€ã®ç¹ããããŸããBigDecimal d1 = new BigDecimal("1.1"); BigDecimal d2 = new BigDecimal("1.10"); System.out.println(d1.equals(d2));
å®éãd1 ãš d2 ã¯åãæ°å€ãè¡šããŸãããequals ã¯æ°å€ã®å€ã ãã§ãªãçŸåšã®é åº (å°æ°ç¹ä»¥äžã®æ¡æ°) ãæ¯èŒãããããfalse ãè¿ããŸããããã¯ããã¥ã¡ã³ãã«æžãããŠããŸãããequals ãªã©ã®ããªãã¿ã®ã¡ãœããã®ããã¥ã¡ã³ããèªã人ã¯ã»ãšãã©ããªãã§ãããããã®ãããªåé¡ã¯ããã«ã¯èµ·ãããªããããããŸãããæ®å¿µãªãããFindBugs èªäœã¯ããã«ã€ããŠèŠåããŸãããããã®ãã°ãèæ
®ãã人æ°ã®ããæ¡åŒµæ©èœ fb-contrib ããããŸãã
MDM_BIGDECIMAL_EQUALS 2 ã€ã® java.math.BigDecimal æ°å€ãæ¯èŒããããã«ãequals() ãåŒã³åºãããŸããããã¯éåžžééãã§ãã2 ã€ã® BigDecimal ãªããžã§ã¯ãã¯ãå€ãšã¹ã±ãŒã«ã®äž¡æ¹ãçããå Žåã«ã®ã¿çããããã2.0 㯠2.00 ãšçãããªããŸãããBigDecimal ãªããžã§ã¯ãã®æ°åŠçç䟡æ§ãæ¯èŒããã«ã¯ã代ããã« CompareTo() ã䜿çšããŸãã
æ¹è¡ãš printf
å€ãã®å ŽåãC ã®åŸã« Java ã«åãæ¿ããããã°ã©ããŒã¯ã PrintStream.printf (ããã³PrintWriter.printfãªã©) ãåãã§èŠã€ããŸãããªãã»ã©ãC ãšåãããã«ãæ°ããããšãåŠã¶å¿ èŠããªãããšã¯ããããŸãããå®éã«ã¯éãããããŸãããã®ãã¡ã® 1 ã€ã¯è¡ã®ç¿»èš³ã«ãããŸããC èšèªã¯ããã¹ã ã¹ããªãŒã ãšãã€ã㪠ã¹ããªãŒã ã«åãããŠããŸããäœããã®æ¹æ³ã§ã\nãæåãããã¹ã ã¹ããªãŒã ã«åºåãããšãã·ã¹ãã äŸåã®æ¹è¡ (Windows ã§ã¯ã\r\nã) ã«èªåçã«å€æãããŸããJava ã«ã¯ãã®ãããªåé¢ã¯ãããŸãããæ£ããæåã·ãŒã±ã³ã¹ãåºåã¹ããªãŒã ã«æž¡ãããå¿ èŠããããŸããããã¯ãããšãã°ãPrintStream.println ãã¡ããªã®ã¡ãœããã«ãã£ãŠèªåçã«è¡ãããŸãããã ããprintf ã䜿çšããå Žåããã©ãŒãããæåå㧠'\n' ãæž¡ããšãã·ã¹ãã ã«äŸåããæ¹è¡ã§ã¯ãªããåãªã '\n' ã«ãªããŸããããšãã°ã次ã®ã³ãŒããæžããŠã¿ãŸããã:System.out.printf("%s\n", "str#1"); System.out.println("str#2");
çµæããã¡ã€ã«ã«ãªãã€ã¬ã¯ããããšã次ã®ããšãããããŸã: ãã®ããã«ã1 ã€ã®ã¹ã¬ããå
ã§æ¹è¡ã®å¥åŠãªçµã¿åãããåŸãããå¯èœæ§ããããããã¯ããããã«èŠããäžéšã®ããŒãµãŒã®å¿ãé©ãããå¯èœæ§ããããŸããç¹ã«äž»ã« Unix ã·ã¹ãã ã§äœæ¥ããŠããå Žåããã®ãšã©ãŒã¯é·ãéæ°ã¥ãããªãå¯èœæ§ããããŸããprintf ã䜿çšããŠæå¹ãªæ¹è¡ãæ¿å
¥ããã«ã¯ãç¹æ®ãªæžåŒèšå®æåã%nãã䜿çšãããŸããããã«ã€ã㊠FindBugs ã¯æ¬¡ã®ããã«æžããŠããŸãã
VA_FORMAT_STRING_USES_NEWLINE: TestNewline.main(String[]) ã§ã¯æžåŒæååã« \n ã§ã¯ãªã %n ã䜿çšããå¿ èŠããããŸãããã®æžåŒæååã«ã¯æ¹è¡æå (\n) ãå«ãŸããŠããŸãããã©ãŒãããæååã§ã¯ãäžè¬ã«ããã©ãããã©ãŒã åºæã®è¡åºåãæåãçæãã %n ã䜿çšããããšããå§ãããŸããããããäžéšã®èªè ã«ãšã£ãŠã¯ãäžèšã®å 容ã¯ãã¹ãŠé·ãéç¥ãããŠããããšã§ããããããããéçã¢ãã©ã€ã¶ããã¯ã䜿çšãããŠããããã°ã©ãã³ã°èšèªã®æ°ããæ©èœãæããã«ãªãèå³æ·±ãèŠåã圌ãã«å±ãããšã¯ã»ãŒç¢ºå®ã§ãã
GO TO FULL VERSION