$ java -cp target/classes com.ankurm.reflection.MethodHandlesDemo

== 1. Look up once, call many times ==
twice(21)        = 42
balance()        = 50
handle type      = (Account)long

== 2. invokeExact is exact; invoke adapts ==
invokeExact, wrong return type -> WrongMethodTypeException
  handle's method type (Account)long but found (Account)Object
invoke (boxing)  = 50 (Long)

== 3. Handles compose ==
bindTo(acct)     = 50
after deposit10  = Account[erin, 60]
balance as text  = "60"

== 4. Access is checked when you look up, not when you call ==
findVirtual(private) -> IllegalAccessException
  no such method: com.ankurm.reflection.Account.secret()String/invokeVirtual
privateLookupIn      -> secret-of-erin
privateLookupIn(String) -> IllegalAccessException
  module java.base does not open java.lang to unnamed module @135fbaa4

== 5. VarHandle: typed, atomic field access ==
get              = 60
CAS(60 -> 100)   = true, balance now 100
CAS(60 -> 200)   = false, balance now 100
getAndAdd(5)     = was 100, now 105
set on final field -> UnsupportedOperationException
array element CAS-able: counts[1] = 7
