Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Javaの型とAI時代に型が大事な理由 / java types and type in AI...

Javaの型とAI時代に型が大事な理由 / java types and type in AI era

2026-06-05に開催されたPython Meetup Fukuoka #7での登壇資料です
https://lycorptech-fukuoka.connpass.com/event/392050/

Avatar for Naoki Kishida

Naoki Kishida

June 05, 2026

More Decks by Naoki Kishida

Other Decks in Programming

Transcript

  1. ܕͷೖޱ 1ZUIPOʹ΋ܕ͸͋Δɻͨͩ͠࢖ΘΕํ͕ҧ͏ w 1ZUIPOͰ͸஋͕࣮ߦ࣌ͷܕΛ࣋ͭ w ܕΞϊςʔγϣϯ͸πʔϧ΍*%&͕׆༻͢Δ৘ใ w ඪ४ͷ࣮ߦ࣌Ͱ͸جຊతʹڧ੍͞Εͳ͍ w +BWBͰ͸ܕʹ߹Θͳ͍ίʔυ͸ίϯύΠϧͰࢭ·Δ

    # Python def get_user_name(user_id: int) -> str: ... get_user_name("abc") # ࣮ߦ࣌ʹඞͣࢭ·Δͱ͸ݶΒͳ͍ // Java String name = "Alice"; name = 123; // ίϯύΠϧΤϥʔ ܕͷೖޱ 
  2. ܕͷೖޱ ܕͱ͸ʮ໿ଋʯͰ͋Δ w ͦͷ஋͕ԿͰ͋Δ͔ w ͦͷ஋ʹԿ͕Ͱ͖Δ͔ w ͦͷ஋ΛͲ͏ѻͬͯ͸͍͚ͳ͍͔ w ܕ͸ίϝϯτͰ͸ͳ͘ɺίϯύΠϥ͕ݕࠪͰ͖Δ໿ଋ

    record UserId(String value) {} record EmailAddress(String value) {} void sendMail(EmailAddress email, MailTitle title, MailBody body) { ... } sendMail(title, email, body); // ίϯύΠϧΤϥʔ ܕͷೖޱ 
  3. +BWBͷܕͷجຊ +BWBͷܕ͸େ͖͘छྨ +BWBͷܕ جຊܕ QSJNJUJWFUZQF ࢀরܕ SFGFSFODFUZQF int / long

    / double / boolean ... String / LocalDate / User / int[] ... ஋ͦͷ΋ͷ ΦϒδΣΫτ΁ͷࢀর +BWBͷܕͷجຊ 
  4. +BWBͷܕͷجຊ ࢀরܕΦϒδΣΫτ΁ͷࢀর w ม਺͸ΦϒδΣΫτͦͷ΋ͷͰ͸ͳ͘ࢀরΛ࣋ͭ w ΦϒδΣΫτʹ͸JEFOUJUZ͕͋Δ w ಺༰͕ಉ͡Ͱ΋ɺಉ͡ΦϒδΣΫτͱ͸ݶΒͳ͍ w ͲͷΦϒδΣΫτ΋ࢦ͍ͯ͠ͳ͍ঢ়ଶ͕OVMM

    record Point(int x, int y) {} Point p1 = new Point(1, 2); Point p2 = new Point(1, 2); System.out.println(p1.equals(p2)); // true System.out.println(p1 == p2); // false +BWBͷܕͷجຊ 
  5. +BWBͷܕͷجຊ JEFOUJUZͱFRVBMJUZ JEFOUJUZ ಉ͡ݸମ͔ʁ FRVBMJUZ ಺༰ͱͯ͠౳͍͔͠ʁ ը໘"ͷʮొ࿥ʯϘλϯ ը໘#ͷʮొ࿥ʯϘλϯ ϥϕϧ͸ಉ͡Ͱ΋ผ෺ 

     ಉ͡೔෇ͳΒಉ͡ҙຯ ΦϒδΣΫτʹ͸JEFOUJUZ͕͋Δɻ஋ʹ͸JEFOUJUZ͕ෆཁͳ͜ͱ͕ଟ͍ɻ +BWBͷܕͷجຊ 
  6. +BWBͷܕͷجຊ OVMMԿ΋ࢦ͍ͯ͠ͳ͍ࢀর w ࢀরܕ͸OVMMΛ࣋ͯΔ w جຊܕ͸OVMMʹͳΒͳ͍ w ܕͱͯ͠͸4USJOHͰ΋ɺ࣮ମ͕ͳ͍͜ͱ͕͋Δ w ܕ͸ڧྗ͕ͩɺOVMMͱ͍͏͕݀͋Δ

    String name = null; System.out.println(name.length()); // NullPointerException int age = null; // ίϯύΠϧΤϥʔ +BWBͷܕͷجຊ 
  7. ΫϥεɾΠϯλʔϑΣʔεɾଟ૬ܕɾ૯শܕ ΫϥεͱΠϯλʔϑΣʔε w ΫϥεԿͰ͋Δ͔Ͳ͏࣮૷͞Ε͍ͯΔ͔ w ΠϯλʔϑΣʔεԿ͕Ͱ͖Δ͔ w ܕΛݟΔ͚ͩͰɺݺ΂Δૢ࡞͕෼͔Δ interface Animal

    { void speak(); } class Dog implements Animal { public void speak() { System.out.println("wan"); } } void speakTwice(Animal animal) { animal.speak(); animal.speak(); } ΫϥεɾΠϯλʔϑΣʔεɾଟ૬ܕɾ૯শܕ 
  8. ΫϥεɾΠϯλʔϑΣʔεɾଟ૬ܕɾ૯শܕ ଟ૬ܕ(͍ΘΏΔܧঝ)ڞ௨ͷܕͱͯ͠ѻ͏ w ͍͔ͭ͘ͷ۩ମܕΛڞ௨ͷܕͱͯ͠ѻ͏ w ಉ͡ݺͼग़͠Ͱ΋࣮ମʹΑͬͯಈ͖͕มΘΔ w ͦͷܕʹ͋Δૢ࡞͚ͩΛݺ΂Δ w "*ʹ΋ʮͰ͖Δ͜ͱ

    Ͱ͖ͳ͍͜ͱʯΛࣔͤΔ Animal animal = new Dog(); animal.speak(); // wan animal = new Cat(); animal.speak(); // nya void process(Animal animal) { animal.fly(); // ίϯύΠϧΤϥʔ } ΫϥεɾΠϯλʔϑΣʔεɾଟ૬ܕɾ૯শܕ 
  9. ΫϥεɾΠϯλʔϑΣʔεɾଟ૬ܕɾ૯শܕ ૯শܕ(δΣωϦΫε)ܕΛύϥϝʔλʹ͢Δ w -JTU5ͷ 5͸ʮத਎ͷܕʯΛද͢ w -JTU4USJOH͸ 4USJOHͷϦετ w -JTU*OUFHFS͸

    *OUFHFSͷϦετ w த਎ͷܕ·ͰίϯύΠϥ͕ݕࠪ͢Δ List<String> names = new ArrayList<>(); names.add("Alice"); // OK names.add(123); // ίϯύΠϧΤϥʔ String name = names.get(0); ΫϥεɾΠϯλʔϑΣʔεɾଟ૬ܕɾ૯শܕ 
  10. ΫϥεɾΠϯλʔϑΣʔεɾଟ૬ܕɾ૯শܕ ଟ૬ܕ WT૯শܕ w ଟ૬ܕ۩ମܕΛڞ௨ͷܕͱͯ͠ѻ͏ w ૯শܕܕͷҧ͍Λอͬͨ··ڞ௨Խ͢Δ w ଟ૬͸ʮͰ͖Δ͜ͱʯʹ஫໨͢Δ w

    ૯শܕ͸ʮܕͷରԠؔ܎ʯʹ஫໨͢Δ void makeSwim(Swimmable x) { x.swim(); } static <T> T first(List<T> xs) { return xs.get(0); } ΫϥεɾΠϯλʔϑΣʔεɾଟ૬ܕɾ૯শܕ 
  11. ܕ͸ূ໌Ͱ͋Δ ܕΛ໋୊ɺ஋Λূڌͱͯ͠ݟΔ w ܕ"ͷ஋͕͋Δ"Ͱ͋Δূڌ͕͋Δ w 'VODUJPO" #"ͷূڌ͔Β#ͷূڌΛ࡞ΕΔ w ͭ·Γ'VODUJPO" #͸ʮ"ͳΒ͹#ʯ

    w ͜ͷݟํ͕ʮܕ͸ূ໌ʯͷೖޱ Function<A, B> f; // A ͳΒ͹ B A a; // A Ͱ͋Δ B b = f.apply(a); // ͕ͨͬͯ͠ B Ͱ͋Δ ܕ͸ূ໌Ͱ͋Δ 
  12. ܕ͸ূ໌Ͱ͋Δ ڕɾࡪɾӭ͛ΔূڌܕͰද͢ w *T4BMNPOࡪͰ͋Δূڌ w *T'JTIڕͰ͋Δূڌ w $BO4XJNӭ͛Δূڌ record IsSalmon(String

    name) {} record IsFish(String name) {} record CanSwim(String name) {} Function<IsSalmon, IsFish> salmonIsFish = s -> new IsFish(s.name()); Function<IsFish, CanSwim> fishCanSwim = f -> new CanSwim(f.name()); ܕ͸ূ໌Ͱ͋Δ 
  13. ܕ͸ূ໌Ͱ͋Δ ࡪͳΒڕɺڕͳΒӭ͛Δɺ͔ͩΒࡪ͸ӭ͛Δ w *T4BMNPO*T'JTI w *T'JTI$BO4XJN w *T4BMNPO$BO4XJNΛ DPNQPTFͰ࡞Δ w

    ূڌΛͭͳ͛Δͷ͕ਪ࿦ Function<IsSalmon, CanSwim> salmonCanSwim = compose(salmonIsFish, fishCanSwim); CanSwim proof = salmonCanSwim.apply( new IsSalmon("αέ") ); ܕ͸ূ໌Ͱ͋Δ 
  14. ܕ͸ূ໌Ͱ͋Δ ͘͡Β͸ӭ͛ΔɻͰ΋ڕͱ͸ಋ͚ͳ͍ w *T8IBMF$BO4XJN͸͋Δ w *T'JTI$BO4XJN΋͋Δ w Ͱ΋ *T8IBMF*T'JTI͸࡞Εͳ͍ w

    ʮӭ͛ΔͳΒڕʯͱ͍͏ϧʔϧ͸ͳ͍ record IsWhale(String name) {} Function<IsWhale, CanSwim> whaleCanSwim = w -> new CanSwim(w.name()); Function<IsFish, CanSwim> fishCanSwim = ...; // Function<IsWhale, IsFish> whaleIsFish = ? // ࡐྉ͕ͳ͍ͷͰಋ͚ͳ͍ ܕ͸ূ໌Ͱ͋Δ 
  15. ܕ͸ূ໌Ͱ͋Δ ૯শܕͰࡾஈ࿦๏ͷϑϨʔϜΛॻ͘ w "ͳΒ͹# w #ͳΒ͹$ w ͕ͨͬͯ͠"ͳΒ͹$ w ۩ମతͳܕʹґଘ͠ͳ͍ਪ࿦ύλʔϯ

    static <A, B, C> Function<A, C> compose( Function<A, B> aToB, Function<B, C> bToC ) { return a -> bToC.apply(aToB.apply(a)); } ܕ͸ূ໌Ͱ͋Δ 
  16. ܕ͸ূ໌Ͱ͋Δ ܕ͕௨Δͱ͸Ͳ͏͍͏͜ͱ͔ w ܕͱͯ͠දݱ͞Εͨલఏ͔Βɺ w ܕͱͯ͠ڐ͞Εͨ݁࿦͚ͩΛಋ͍͍ͯΔ w ܕ͕௨Βͳ͍ ݁࿦Λಋͨ͘Ίͷূڌ͕଍Γͳ͍ w

    *T8IBMF*T'JTI͸ূڌ͕ͳ͍ͷͰ࡞Εͳ͍ // ͋Δ: ͘͡Β -> ӭ͛Δ Function<IsWhale, CanSwim> whaleCanSwim; // ͋Δ: ڕ -> ӭ͛Δ Function<IsFish, CanSwim> fishCanSwim; // ͳ͍: ӭ͛Δ -> ڕ // ͔ͩΒ IsWhale -> IsFish ͸ಋ͚ͳ͍ ܕ͸ূ໌Ͱ͋Δ 
  17. ܕ͸ূ໌Ͱ͋Δ ͨͩ͠ɺܕ͚ͩͰ͢΂ͯ͸ূ໌Ͱ͖ͳ͍ w +BWBͷܕͰϓϩάϥϜͷਖ਼͠͞Λશ෦ূ໌Ͱ͖ΔΘ͚Ͱ͸ͳ͍ w AJOUEJWJEF JOUB JOUC A͸ܕͱͯ͠͸ਖ਼͍͠ w

    ͔͠͠C͸࣮ߦ࣌ʹ໰୊ʹͳΔ w ܕΛ޻෉͢ΔͱɺอূͰ͖ΔൣғΛ޿͛ΒΕΔ record NonZeroInt(int value) { public NonZeroInt { if (value == 0) { throw new IllegalArgumentException("zero"); } } } int divide(int a, NonZeroInt b) { return a / b.value(); } divide(10, 0); // ίϯύΠϧΤϥʔ ܕ͸ূ໌Ͱ͋Δ 
  18. "*࣌୅ͷܕ ܕ͸"*ͷग़ྗΛ࠾఺͢Δج४Ͱ͋Δ "*͕ ίʔυΛॻ͘ ίϯύΠϥ͕ ܕΛݕࠪ ܕΤϥʔ͕ ग़Δ "*ਓ͕ؒ मਖ਼

    ܕͷ໿ଋΛ ຬͨ͢ ܕ͕͋Δͱɺ"*ͷʮ΋ͬͱ΋Β͍ؒ͠ҧ͍ʯΛػցతʹམͱͤΔ ܕ͸ɺ"*Λ৴༻͢ΔͨΊͰ͸ͳ͘ɺ"*Λ৴༻͗͢͠ͳ͍ͨΊͷ҆શ૷ஔ "*࣌୅ͷܕ 
  19. $MPTJOH ·ͱΊ  +BWBͷܕ͸جຊܕͱࢀরܕʹେ͖͘෼͔ΕΔ  JEFOUJUZFRVBMJUZOVMM͸+BWBͷܕཧղͷॏཁϙΠϯτ  ଟ૬ܕ͸ڞ௨ͷܕͱͯ͠ѻ͍ɺ૯শܕ͸ܕΛอͬͯڞ௨Խ͢Δ  ૯শܕʴؔ਺Ͱɺࡾஈ࿦๏ͷΑ͏ͳਪ࿦ϑϨʔϜΛදͤΔ

     ܕ͸໋୊ɺ஋͸ূڌɺؔ਺ݺͼग़͠͸ਪ࿦ͱͯ͠ݟΒΕΔ  "*࣌୅ʹ͸ɺܕ͸࢓༷ɾ੍໿ɾ࠾఺ج४ʹͳΔ "*͕ίʔυΛॻ࣌͘୅ʹ͸ɺʮؒҧͬͨ΋ͷΛॻ͚ͳ͍ʯઃܭ͕ॏཁʹͳΔɻ $MPTJOH