KAnnotatorã§Javaã©ã¤ãã©ãªã§ãNull-Safetyæ©è½ã使ã #Kotlin
Kotlin Advent Calendar 2013 22æ¥ç®ã®ã¨ã³ããªã§ãã
Javaã®ã©ã¤ãã©ãªä½¿ããã
Kotlin使ã£ã¦ã¦æ®éã«ãµã¼ããã¼ãã£è£½ã®ã©ã¤ãã©ãªä½¿ãã¾ããããä¾ãã°Joda-Time使ã£ã¦ãããªæãã§ã
fun main(args: Array<String>) { val today = LocalDate.now() val first = today!!.dayOfMonth()!!.withMinimumValue() println(first!!.toString("mm/dd")) }
ãããå¢ãããæï¼ï¼
fun main(args: Array<String>) { val today = LocalDate.now() val first = today?.dayOfMonth()?.withMinimumValue() println(first?.toString("mm/dd")) }
ãããçåããæï¼
便å©ãªæ©è½ã§ããã¯ãã®Kotlinã®Null-Safetyæ©è½ã§ãããJavaã©ã¤ãã©ãªã§ã¡ã½ãããã§ã¼ã³ãããã¨ããªããã¯ãã©ããã¦ãå¾®å¦ãªæãã«ãªãã¾ãããã®ã¡ã½ãã絶対nullè¿ããªãããï¼ã£ã¦è¨ããããªãããªãããã£ã¡ãnullä¸å®ãªäººã®ã³ã¼ãã¿ããã空æ°èªãã§æ¬²ããã§ãããã
External Annotations
ããã解決ããæ段ã¨ãã¦ãJetBrainsãç¨æãã¦ããåã¢ããã¼ã·ã§ã³ãããã¾ããJavaå´ã®ã³ã¼ãã§@NotNull*1ã@Nullable*2ãä»ãã¦ããã¨ãKotlinã§ã¯ãããNull-Safetyæ©è½ã¨ãã¦è§£éãã¦ããã¾ãã*3
ãã ãã ããã¨è¨ã£ã¦Joda-Timeã¨ãæ¢åã©ã¤ãã©ãªããã£ã¦@NotNullä»ãã¦ä½¿ããã¨è¨ãããã°ããããªããã©ããããã¨æ¯åãã£ã¦ãã大å¤ã ããâ¦â¦ã£ã¦ã¨ããã§ç»å ´ããã®ããExternal Annotationsãã§ãã
External Annotationsã¯ãã©ã¤ãã©ãªãæ¹å¤ããã«XMLã§ããã®ã¡ã½ããã«å¯¾ãã¦ãã®ã¢ããã¼ã·ã§ã³ãä»ãããã¿ãããªæãã§ã¢ããã¼ã·ã§ã³ãå¤é¨å®ç¾©ã§ãã¾ããIntelliJ IDEAã®æ©è½ã®1ã¤ã§ãã*4
Joda-Timeã®nowã¡ã½ããã¾ã§ç§»åãã¦ãããããã«Alt+Enterãæ¼ãã¾ãã
ãªããããã£ã½ãã®åºã¾ããããAnnotate method 'now' as @NotNullããé¸æãã¾ãããã¶ãååã¯External Annotationsã®XMLãä¿åããå ´æãèãããã®ã§ãé©å½ã«é¸ã³ã¾ãããã
é¸æãããã£ã¬ã¯ããªã®ä¸ã«ããã±ã¼ã¸æ§æåã®ãã£ã¬ã¯ããªãåºæ¥ã¦ãã¾ããããã«annotations.xmlã¨ãããã¡ã¤ã«ããã£ã¦ãä¸èº«ã¯ãããªæãã«ãªã£ã¦ããã¯ãã
<root> <item name='org.joda.time.LocalDate org.joda.time.LocalDate now()'> <annotation name='org.jetbrains.annotations.NotNull'/> </item> </root>
å ã®ã³ã¼ãã«æ»ãã¨ãè¦ååºã¦ã¾ããã
ããã§ãJoda-Timeã«ã¯ä½ä¸ã¤æãå ãããã¨ãªããã¡ã½ããã«@NotNullã¢ããã¼ã·ã§ã³ãä»ãã¦ãKotlinå´ãããnowã¡ã½ããã®æ»ãå¤ã¯Null-Safeåã§æ±ããããã«ãªãã¾ããã
ã§ãããdayOfMonthãwithMinimumValueãããã«ä»ã®ã¡ã½ãããå ¨é¨åããã¨ãããã£ã¦è¨ãããã°ããããªããã©ããããã¨ãã£ã¦ãããªãããã
KAnnotator
External Annotations便å©ãªãã§ããããããä¸ã¤ä¸ã¤ããã®ã¯ãããã«çæ°ã®æ²æ±°ã§ããããã@NotNullã@Nullableã®ã¢ããã¼ã·ã§ã³ãé¸æããã®ã¯èªåãªã®ã§ããã¹ãå¯è½æ§ãããã¾ããããã§ãKAnnotatorãã®ç»å ´ã§ãã
KAnnotator㯠任æã®ã©ã¤ãã©ãªã«å«ã¾ããå ¨ã¡ã½ããã®ä¸èº«ãæ¨è«ããExternal Annotationsãçæãã IntelliJ IDEAã®ãã©ã°ã¤ã³ã§ããGitHubã§ç®¡çããã¦ãã¦ãIntelliJ IDEAã®ãã©ã°ã¤ã³ãªãã¸ããªããã¤ã³ã¹ãã¼ã«ã§ãã¾ãã
æ°è¦ãã©ã°ã¤ã³ã¤ã³ã¹ãã¼ã«ã§æ¤ç´¢ããã¯ã¹ã«"Kotlin"ã¨å ¥åãã*5ã¨KAnnotatorãåºç¾ããã®ã§ãã¤ã³ã¹ãã¼ã«ãã¾ãã
ã¡ãªã¿ã«ãããã¨ã³ããªæ¸ãã¦ãæç¹ã§ã§Kotlinã®Downdowdæ°ã26000ãããã«å¯¾ãã¦KAnnotatorã1650件ãããã§ããããã¾ãç¥ããã¦ãªãï¼
ã¤ã³ã¹ãã¼ã«ãçµãã£ã¦åèµ·åããããã¡ãã¥ã¼ã®Analyzeã«ãAnnotate Jar Files...ãã£ã¦é ç®ã追å ããã¦ãã®ã§é¸æãã¾ãã
ã¡ãã£ã¨å å·¥ãã¦ã¾ãããããªæãã®ã¦ã£ã³ãã¦ãåºã¦ããã®ã§ãJoda-Timeã®ã©ã¤ãã©ãªã«ãã§ãã¯ãå ¥ãã¦ãOKæ¼ãã¾ãããããªã«å¾ ããã«External Annotationsã®çæãå®äºãã¾ãã
çæããXMLãè¦ã¦ã¿ãã¨ã大éã®ã¡ã½ããã«å¯¾ãã¦@NotNullã®External Annotationså®ç¾©ãæ¸ããã¦ãã¾ãã@Nullableã®External Annotationsã¯ããããå®ç¾©ãã¦ããªãããã§ãã*6
å度ã³ã¼ããè¦ã¦ã¿ãã¨ãä»ã®å®å ¨å¼ã³åºãã«ãè¦åãåºã¦ãã¾ãã
ã¨ããããã§ãããã§Kotlinã¯ç©ºæ°ãèªãããããªãã¾ããï¼ãã£ãã¼ï¼
KAnnotator / External Annotations ã®ãããã¨ãã
- Javaã©ã¤ãã©ãªã§Null-Safetyæ©è½ãç°¡åã«ä½¿ããï¼ï¼ï¼
- ã©ã¤ãã©ãªå´ã®å¯¾å¿ãå¾ ããã«ã@NotNull, @Nullableã¢ããã¼ã·ã§ã³ã使ãã
- åã¢ããã¼ã·ã§ã³ã大éã§ã³ã¼ãããã¡ããã¡ãï¼ã¿ãããªæãã«ãªããªã
- ã©ã¤ãã©ãªå´ã§External Annotationsãæä¾ããã°Kotlinå´ã§ä½ã®éåæããªã使ãã
- Kotlinï¼External Annotationsã§Javaå´ããã¯åã¢ããã¼ã·ã§ã³ã¤ãã¦ãããã«è¦ãã
ä»å¾Java8ãæ£å¼ãªãªã¼ã¹ããã¦ãKotlinã§ã¯ãªãã¨ãåã¢ããã¼ã·ã§ã³ãæ´»ç¨ããã·ã¼ã³ã¯ããããå¢ãã¦ããã¨æãã®ã§ãããããå ´åãç°¡åã«å¯¾å¿ã§ããããªã®ãããã§ãããJetBrainsã®å ¬å¼ã§ããAnnotate The Worldããªãã¦è¨ã£ã¦ã¾ããã
ç¾ç¶KAnnotatorã¯Nullabilityã¢ããã¼ã·ã§ã³ãã対å¿ãã¦ããªãã¿ããã§ãããä»å¾ã¯@Mutable, @ReadOnlyãªã©ã®ä»ã¢ããã¼ã·ã§ã³ã¸ã®å¯¾å¿ãã@NonNullã¨@NotNullã®éãã®å¸åã¨ãããã®ã¸ãã対å¿ãã¦ã»ããï¼
Javaã®æ¨æºã©ã¤ãã©ãªã®External Annotations
ãã®ã¨ã³ããªãæ¸ãããã«IntelliJ IDEAã»ããã¢ãããã¦ã¦ä»æ´æ°ã¥ãããã§ããã©*7ãæ¨æºã©ã¤ãã©ãªã£ã¦nullãè¿ããªãã¡ã½ããã¯Null-Safeåãè¿ãããã«ãªã£ã¦ããã§ããã
ãã¨ãã°ãããªã³ã¼ãã¨ãã
fun main(args: Array<String>) { val cal = Calendar.getInstance(); cal.set(Calendar.DATE, cal.getActualMinimum(Calendar.DATE)) println("${cal.get(Calendar.MONTH) + 1}/${cal.get(Calendar.DATE)}") }
å¤æ°calããå¼ã³åºãã¦ãã¡ã½ããã®åã«ã¯?ãããã¯ãããããExternal Annotationsã§ãã£ã¦ã¾ããã
Project Structureéãã¦âPlatform Settingsã®SDKsâAnnotationsã¿ããéãã¨ãIntellij IDEAå´ã§æã£ã¦ãJDKã®External Annotationsã¨ãKotlinã®External Annotationsãã¤ã³ãã¼ãããã¦ã¾ãã
ã¡ãªã¿ã«ãããFiles.get(String, String...)ã@NotNullãããªãã£ã½ããã§ããã©ãããã£ã¦nullè¿ãå¯è½æ§ãããã ã£ãããªâ¦â¦ï¼
ã¾ã¨ã
Kotlinã§Javaã©ã¤ãã©ãªä½¿ããªãKAnnotator使ããªãçç±ãªãæ°ããã¦ããï¼è©¦ãã¦ãªããã©AndroidSDKã®ã©ã¤ãã©ãªã対å¿ã§ãããã
ä»å試ããã³ã¼ãGitHubã«ãããã®ã§URLè²¼ã£ã¦ããã¾ã https://github.com/clomie/KotlinKAnnotatorTest
å人çã«ã¯ãã³ã¼ããããã·ã³ãã«ã«æ¸ããã¯ãã®Kotlinã§ãè¨èªæ©è½ã®å£²ãã§ããNull-Safetyæ©è½ãJavaã©ã¤ãã©ãªã§å¾®å¦ãªæãã«ãªã£ã¦ãã¾ãã®ãKotlinã®æ®å¿µãªé¨åã ã¨æã£ã¦ããã®ã§ãããã解決ã§ããä»Kotlinæå¼·ãªããããªããã¨æã£ã¦ãã¾ããã
Kotlinæå¼·ï¼Kotlinããããï¼ï¼¼ï¾ï¾ï½¶ï¾ï½¬ï½°ï¾ï¼
ãã¨ãããªã«é·ãã¨ã³ããªæ¸ããã®ä¹ ã ãªã®ã§ã¡ãã£ã¨ç²ãã¾ããã
åèURL
Using External Annotations | Project Kotlin
Kotlin M4 is Out! | Project Kotlin
*1:org.jetbrains.annotations.NotNull
*2:org.jetbrains.annotations.Nullable
*3:以åããããæ©è½ããã°ããã®ã«ã¿ãããªè©±ããã¦ããã§ãããå®ã¯M3ãããããåºæ¥ãããã«ãªã£ã¦ãããã
*4:ãã¶ã
*5:KAnnotatorã§ãOK
*6:ãã¶ãâ¦â¦
*7:ã ãããããã®ã¨ã³ããªæ¸ãã¦ã