Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Kotlin2でdataクラスの copyメソッドを禁止する/Data class copy ...
Search
A1
October 23, 2024
Programming
1.1k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Kotlin2でdataクラスの copyメソッドを禁止する/Data class copy function to have the same visibility as constructor
Server-Side Kotlin LT大会 vol.13 資料
A1
October 23, 2024
More Decks by A1
See All by A1
プロダクトのことは何でもNotebookLMに聞こう / NotebookLM for on boarding
eichisanden
2
160
短納期でローンチした新サービスをJavaで開発した話/launched new service using Java
eichisanden
6
4.4k
トラブルゼロで乗り切ったTypeScript移行/trouble-free TypeScript migration
eichisanden
3
3.8k
スクラム開発チームをLessでスケールさせた話/Scaling Scrum team with Less
eichisanden
0
6.4k
息の長いサービスのフロントエンドを少し改善する営み/frontend-improvement
eichisanden
3
3.2k
実はGitLabで使えるmermaid.js/gitlab-mermaid.js
eichisanden
1
870
既存 Web アプリケーションへの React.js 適用/react for web application
eichisanden
0
2k
楽楽明細でやってるChatOps/Development with ChatOps
eichisanden
0
1.3k
jshell概要
eichisanden
0
120
Other Decks in Programming
See All in Programming
Embedded Swiftで作る自作USBデバイス によるiOSデバイスの自動テスト / iOSDC Japan 2026 glassfiber
glassfiber
0
310
外から家のPCの電源入れたい!をPHPで解決する
kawashimo0
1
120
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
150
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
34
16k
Are APIs Still Relevant in the AI Era?
soyuka
0
440
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
490
dotNET_vulnclicker_intro.pdf
deka_morita
0
120
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
260
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
270
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
200
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
150
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
490
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
7k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
1k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
510
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
The Pragmatic Product Professional
lauravandoore
37
7.5k
Balancing Empowerment & Direction
lara
6
1.3k
The Curse of the Amulet
leimatthew05
3
15k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
20k
A better future with KSS
kneath
240
18k
WENDY [Excerpt]
tessaabrams
14
40k
The SEO identity crisis: Don't let AI make you average
varn
0
580
Transcript
© 2024 Loglass Inc. 2024.10.25 三田 英一(@eichisanden) Kotlin2でdataクラスの copyメソッドを禁止する Server-Side
Kotlin LT大会 vol.13
© 2024 Loglass Inc. Profile 三田 英一 株式会社ログラス プロダクト開発部 エンジニア
株式会社ログラスに2024年5月に入社。 サーバーサイドはKotlin、フロントエンドは TypeScript+Reactで開発しています。 今まで様々な言語を使ってきましたが Kotlinは堅牢な型がありつつ書き味の良さもあって 1番好きな言語です。 Eiichi Mita
© 2024 Loglass Inc. Contents 1. Kotlin1.9まで 2. Kotlin2から 3.
先行して試す Contents
© 2024 Loglass Inc. Kotlin1.9まで Kotlin1.9まで dataクラスはequals, hashCodeなどを自動生成してくれて便利な反面、 コンストラクタの可視性に関わらず、publicなcopyメソッドを自動生成する問題 がありました。
© 2024 Loglass Inc. Kotlin1.9まで private constructorで外部からコンストラクタの使用を禁止し、Factoryメ ソッドでのインスタンス生成を強制したつもりでも... data class
PositiveInteger private constructor(val number: Int) { companion object { // 0より大きい値しか受け付けないFactoryメソッド fun create(number: Int): PositiveInteger? = if (number > 0) PositiveInteger(number) else null } } fun main() { val positiveNumber = PositiveInteger.create(42) ?: return }
© 2024 Loglass Inc. Kotlin1.9まで 自動生成されたcopyを呼べてしまう!不正なインスタンスを作り放題!! ドメイン層のインスタンスは不正な状態を作られたくないので、この抜け道は困る。 // マイナス値をセットできてしまう! val
negativeNumber = positiveNumber.copy(number = -1)
© 2024 Loglass Inc. Kotlin1.9まで 仕方ないので、意図しないところでcopyを呼び出さないようにArchUnitで チェックしていた。 @Test fun `ドメイン層のデータクラスに付属する
copyメソッドを呼び出すことはできない `() { val allApplicationClasses = ClassFileImporter() .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) .importPackages("com.example") methods() .should(BanDomainLayerDataClassCopyCondition) .check(allApplicationClasses) } private object BanDomainLayerDataClassCopyCondition : ArchCondition<JavaMethod>("data classのcopyは、同じクラス内でしかコールすることができない ") { override fun check(method: JavaMethod, events: ConditionEvents) { if (method.name != "copy\$default") return method.callsOfSelf.forEach { caller -> // this.copyは許容する if (method.owner != caller.originOwner) events.add(SimpleConditionEvent.violated(method,"エラーメッセージ ")) } } }
© 2024 Loglass Inc. Kotlin2から Kotlin2から dataクラスのcopyメソッドの可視性はプライマリコンストラクタと同じになる! いきなりではなく、段階的に実施される。
© 2024 Loglass Inc. タイムライン • フェーズ1: 2.0.20 ←今ここ ◦ 警告が表示されるようになった。
◦ @ConsistentCopyVisibilityで2.2以降の動作を先行してオプトイン可能。 ◦ @ExposedCopyVisibilityで明示的にcopyメソッドを公開可能。 • フェーズ2: 2.2(予定) ◦ 警告表示だった箇所がエラーに変わり、copyメソッドを呼び出せなくなる。 ◦ 互換性のためバイナリから消える訳ではない。 • フェーズ3: 2.3 or 2.4(予定) ◦ copyメソッドの可視性はプライマリコンストラクタと同じになる。 ◦ 役割を終えた@ConsistentCopyVisibilityは廃止される。 Kotlin2から
© 2024 Loglass Inc. 先行して試す Kotlin2.2まで時間があるので、 余裕を持って対応を終わらせておきたい。 (言うほど大変ではないと思いますが)
© 2024 Loglass Inc. 先行して試す @ConsistentCopyVisibilityを指定して2.2の動作をオプトインできる。 @ConsistentCopyVisibility data class PositiveInteger
private constructor(val number: Int) { companion object { fun create(number: Int): PositiveInteger? = if (number > 0) PositiveInteger(number) else null } } fun main() { val positiveNumber = PositiveInteger.create(42) ?: return val negativeNumber = positiveNumber.copy(number = -1) // Cannot access 'fun copy(number: Int = ...): PositiveInteger': it is private in '/PositiveInteger'. }
© 2024 Loglass Inc. 先行して試す アノテーションを個別のクラスに付与するのは現実的ではないので、コンパイラオプ ションで一括指定して、エラーになった箇所を少しずつ直すと良さそう。 // build.gradle.kts tasks
{ named("compileKotlin", KotlinCompilationTask::class.java) { compilerOptions { freeCompilerArgs.add("-Xconsistent-data-class-copy-visibility") } } }
© 2024 Loglass Inc. 先行して試す 明示的に許可したい場合は、@ExposedCopyVisibilityを付与することも可能。 @ExposedCopyVisibility data class PositiveInteger
private constructor(val number: Int) { companion object { fun create(number: Int): PositiveInteger? = if (number > 0) PositiveInteger(number) else null } } fun main() { val positiveNumber = PositiveInteger.create(42) ?: return // エラーにならない val negativeNumber = positiveNumber.copy(number = -1) }
© 2024 Loglass Inc. おわりに Kotlinは互換性や移行期間も考えてくれて 安心して使えると改めて感じました。
© 2024 Loglass Inc. おわりに Kotlin2に上げると 他にもビルドが早くなったり良いことがあるので バージョン上げてきましょう!!
© 2024 Loglass Inc.
© 2024 Loglass Inc. 参考URL • What's new in Kotlin
2.0.20 • [YouTrack]Confusing data class copy with private constructor • [Loglass Tech Blog Sprint] ArchUnitでKotlinのdata classのcopyメ ソッドを禁止する Appendix