Produced by Araxis Merge on 9/25/2018 2:13:09 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.
# | Location | File | Last Modified |
---|---|---|---|
1 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\java\lang\invoke | MethodHandle.java | Mon Jan 22 14:46:52 2018 UTC |
2 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\java\lang\invoke | MethodHandle.java | Wed Sep 12 17:08:45 2018 UTC |
Description | Between Files 1 and 2 |
|
---|---|---|
Text Blocks | Lines | |
Unchanged | 2 | 2910 |
Changed | 1 | 2 |
Inserted | 0 | 0 |
Removed | 0 | 0 |
Whitespace | |
---|---|
Character case | Differences in character case are significant |
Line endings | Differences in line endings (CR and LF characters) are ignored |
CR/LF characters | Not shown in the comparison detail |
No regular expressions were active.
1 | /* | |
2 | * Copyrig ht (c) 200 8, 2013, O racle and/ or its aff iliates. A ll rights reserved. | |
3 | * DO NOT ALTER OR R EMOVE COPY RIGHT NOTI CES OR THI S FILE HEA DER. | |
4 | * | |
5 | * This co de is free software; you can r edistribut e it and/o r modify i t | |
6 | * under t he terms o f the GNU General Pu blic Licen se version 2 only, a s | |
7 | * publish ed by the Free Softw are Founda tion. Ora cle design ates this | |
8 | * particu lar file a s subject to the "Cl asspath" e xception a s provided | |
9 | * by Orac le in the LICENSE fi le that ac companied this code. | |
10 | * | |
11 | * This co de is dist ributed in the hope that it wi ll be usef ul, but WI THOUT | |
12 | * ANY WAR RANTY; wit hout even the implie d warranty of MERCHA NTABILITY or | |
13 | * FITNESS FOR A PAR TICULAR PU RPOSE. Se e the GNU General Pu blic Licen se | |
14 | * version 2 for mor e details (a copy is included in the LIC ENSE file that | |
15 | * accompa nied this code). | |
16 | * | |
17 | * You sho uld have r eceived a copy of th e GNU Gene ral Public License v ersion | |
18 | * 2 along with this work; if not, write to the Fr ee Softwar e Foundati on, | |
19 | * Inc., 5 1 Franklin St, Fifth Floor, Bo ston, MA 0 2110-1301 USA. | |
20 | * | |
21 | * Please contact Or acle, 500 Oracle Par kway, Redw ood Shores , CA 94065 USA | |
22 | * or visi t www.orac le.com if you need a dditional informatio n or have any | |
23 | * questio ns. | |
24 | */ | |
25 | ||
26 | package ja va.lang.in voke; | |
27 | ||
28 | ||
29 | import jav a.util.*; | |
30 | ||
31 | import sta tic java.l ang.invoke .MethodHan dleStatics .*; | |
32 | ||
33 | /** | |
34 | * A metho d handle i s a typed, directly executable reference to an und erlying me thod, | |
35 | * constru ctor, fiel d, or simi lar low-le vel operat ion, with optional | |
36 | * transfo rmations o f argument s or retur n values. | |
37 | * These t ransformat ions are q uite gener al, and in clude such patterns as | |
38 | * {@linkp lain #asTy pe convers ion}, | |
39 | * {@linkp lain #bind To inserti on}, | |
40 | * {@linkp lain java. lang.invok e.MethodHa ndles#drop Arguments deletion}, | |
41 | * and {@l inkplain j ava.lang.i nvoke.Meth odHandles# filterArgu ments subs titution}. | |
42 | * | |
43 | * <h1>Met hod handle contents< /h1> | |
44 | * Method handles ar e dynamica lly and st rongly typ ed accordi ng to thei r paramete r and retu rn types. | |
45 | * They ar e not dist inguished by the nam e or the d efining cl ass of the ir underly ing method s. | |
46 | * A metho d handle m ust be inv oked using a symboli c type des criptor wh ich matche s | |
47 | * the met hod handle 's own {@l inkplain # type type descriptor }. | |
48 | * <p> | |
49 | * Every m ethod hand le reports its type descriptor via the { @link #typ e type} ac cessor. | |
50 | * This ty pe descrip tor is a { @link java .lang.invo ke.MethodT ype Method Type} obje ct, | |
51 | * whose s tructure i s a series of classe s, one of which is | |
52 | * the ret urn type o f the meth od (or {@c ode void.c lass} if n one). | |
53 | * <p> | |
54 | * A metho d handle's type cont rols the t ypes of in vocations it accepts , | |
55 | * and the kinds of transforma tions that apply to it. | |
56 | * <p> | |
57 | * A metho d handle c ontains a pair of sp ecial invo ker method s | |
58 | * called {@link #in vokeExact invokeExac t} and {@l ink #invok e invoke}. | |
59 | * Both in voker meth ods provid e direct a ccess to t he method handle's | |
60 | * underly ing method , construc tor, field , or other operation , | |
61 | * as modi fied by tr ansformati ons of arg uments and return va lues. | |
62 | * Both in vokers acc ept calls which exac tly match the method handle's own type. | |
63 | * The pla in, inexac t invoker also accep ts a range of other call types . | |
64 | * <p> | |
65 | * Method handles ar e immutabl e and have no visibl e state. | |
66 | * Of cour se, they c an be boun d to under lying meth ods or dat a which ex hibit stat e. | |
67 | * With re spect to t he Java Me mory Model , any meth od handle will behav e | |
68 | * as if a ll of its (internal) fields ar e final va riables. This means that any method | |
69 | * handle made visib le to the applicatio n will alw ays be ful ly formed. | |
70 | * This is true even if the me thod handl e is publi shed throu gh a share d | |
71 | * variabl e in a dat a race. | |
72 | * <p> | |
73 | * Method handles ca nnot be su bclassed b y the user . | |
74 | * Impleme ntations m ay (or may not) crea te interna l subclass es of {@co de MethodH andle} | |
75 | * which m ay be visi ble via th e {@link j ava.lang.O bject#getC lass Objec t.getClass } | |
76 | * operati on. The p rogrammer should not draw conc lusions ab out a meth od handle | |
77 | * from it s specific class, as the metho d handle c lass hiera rchy (if a ny) | |
78 | * may cha nge from t ime to tim e or acros s implemen tations fr om differe nt vendors . | |
79 | * | |
80 | * <h1>Met hod handle compilati on</h1> | |
81 | * A Java method cal l expressi on naming {@code inv okeExact} or {@code invoke} | |
82 | * can inv oke a meth od handle from Java source cod e. | |
83 | * From th e viewpoin t of sourc e code, th ese method s can take any argum ents | |
84 | * and the ir result can be cas t to any r eturn type . | |
85 | * Formall y this is accomplish ed by givi ng the inv oker metho ds | |
86 | * {@code Object} re turn types and varia ble arity {@code Obj ect} argum ents, | |
87 | * but the y have an additional quality c alled <em> signature polymorphi sm</em> | |
88 | * which c onnects th is freedom of invoca tion direc tly to the JVM execu tion stack . | |
89 | * <p> | |
90 | * As is u sual with virtual me thods, sou rce-level calls to { @code invo keExact} | |
91 | * and {@c ode invoke } compile to an {@co de invokev irtual} in struction. | |
92 | * More un usually, t he compile r must rec ord the ac tual argum ent types, | |
93 | * and may not perfo rm method invocation conversio ns on the arguments. | |
94 | * Instead , it must push them on the sta ck accordi ng to thei r own unco nverted ty pes. | |
95 | * The met hod handle object it self is pu shed on th e stack be fore the a rguments. | |
96 | * The com piler then calls the method ha ndle with a symbolic type desc riptor whi ch | |
97 | * describ es the arg ument and return typ es. | |
98 | * <p> | |
99 | * To issu e a comple te symboli c type des criptor, t he compile r must als o determin e | |
100 | * the ret urn type. This is b ased on a cast on th e method i nvocation expression , | |
101 | * if ther e is one, or else {@ code Objec t} if the invocation is an exp ression | |
102 | * or else {@code vo id} if the invocatio n is a sta tement. | |
103 | * The cas t may be t o a primit ive type ( but not {@ code void} ). | |
104 | * <p> | |
105 | * As a co rner case, an uncast ed {@code null} argu ment is gi ven | |
106 | * a symbo lic type d escriptor of {@code java.lang. Void}. | |
107 | * The amb iguity wit h the type {@code Vo id} is har mless, sin ce there a re no refe rences of type | |
108 | * {@code Void} exce pt the nul l referenc e. | |
109 | * | |
110 | * <h1>Met hod handle invocatio n</h1> | |
111 | * The fir st time a {@code inv okevirtual } instruct ion is exe cuted | |
112 | * it is l inked, by symbolical ly resolvi ng the nam es in the instructio n | |
113 | * and ver ifying tha t the meth od call is staticall y legal. | |
114 | * This is true of c alls to {@ code invok eExact} an d {@code i nvoke}. | |
115 | * In this case, the symbolic type descr iptor emit ted by the compiler is checked for | |
116 | * correct syntax an d names it contains are resolv ed. | |
117 | * Thus, a n {@code i nvokevirtu al} instru ction whic h invokes | |
118 | * a metho d handle w ill always link, as long | |
119 | * as the symbolic t ype descri ptor is sy ntacticall y well-for med | |
120 | * and the types exi st. | |
121 | * <p> | |
122 | * When th e {@code i nvokevirtu al} is exe cuted afte r linking, | |
123 | * the rec eiving met hod handle 's type is first che cked by th e JVM | |
124 | * to ensu re that it matches t he symboli c type des criptor. | |
125 | * If the type match fails, it means tha t the meth od which t he | |
126 | * caller is invokin g is not p resent on the indivi dual | |
127 | * method handle bei ng invoked . | |
128 | * <p> | |
129 | * In the case of {@ code invok eExact}, t he type de scriptor o f the invo cation | |
130 | * (after resolving symbolic t ype names) must exac tly match the method type | |
131 | * of the receiving method han dle. | |
132 | * In the case of pl ain, inexa ct {@code invoke}, t he resolve d type des criptor | |
133 | * must be a valid a rgument to the recei ver's {@li nk #asType asType} m ethod. | |
134 | * Thus, p lain {@cod e invoke} is more pe rmissive t han {@code invokeExa ct}. | |
135 | * <p> | |
136 | * After t ype matchi ng, a call to {@code invokeExa ct} direct ly | |
137 | * and imm ediately i nvoke the method han dle's unde rlying met hod | |
138 | * (or oth er behavio r, as the case may b e). | |
139 | * <p> | |
140 | * A call to plain { @code invo ke} works the same a s a call t o | |
141 | * {@code invokeExac t}, if the symbolic type descr iptor spec ified by t he caller | |
142 | * exactly matches t he method handle's o wn type. | |
143 | * If ther e is a typ e mismatch , {@code i nvoke} att empts | |
144 | * to adju st the typ e of the r eceiving m ethod hand le, | |
145 | * as if b y a call t o {@link # asType asT ype}, | |
146 | * to obta in an exac tly invoka ble method handle {@ code M2}. | |
147 | * This al lows a mor e powerful negotiati on of meth od type | |
148 | * between caller an d callee. | |
149 | * <p> | |
150 | * (<em>No te:</em> T he adjuste d method h andle {@co de M2} is not direct ly observa ble, | |
151 | * and imp lementatio ns are the refore not required to materia lize it.) | |
152 | * | |
153 | * <h1>Inv ocation ch ecking</h1 > | |
154 | * In typi cal progra ms, method handle ty pe matchin g will usu ally succe ed. | |
155 | * But if a match fa ils, the J VM will th row a {@li nk WrongMe thodTypeEx ception}, | |
156 | * either directly ( in the cas e of {@cod e invokeEx act}) or i ndirectly as if | |
157 | * by a fa iled call to {@code asType} (i n the case of {@code invoke}). | |
158 | * <p> | |
159 | * Thus, a method ty pe mismatc h which mi ght show u p as a lin kage error | |
160 | * in a st atically t yped progr am can sho w up as | |
161 | * a dynam ic {@code WrongMetho dTypeExcep tion} | |
162 | * in a pr ogram whic h uses met hod handle s. | |
163 | * <p> | |
164 | * Because method ty pes contai n "live" { @code Clas s} objects , | |
165 | * method type match ing takes into accou nt both ty pes names and class loaders. | |
166 | * Thus, e ven if a m ethod hand le {@code M} is crea ted in one | |
167 | * class l oader {@co de L1} and used in a nother {@c ode L2}, | |
168 | * method handle cal ls are typ e-safe, be cause the caller's s ymbolic ty pe | |
169 | * descrip tor, as re solved in {@code L2} , | |
170 | * is matc hed agains t the orig inal calle e method's symbolic type descr iptor, | |
171 | * as reso lved in {@ code L1}. | |
172 | * The res olution in {@code L1 } happens when {@cod e M} is cr eated | |
173 | * and its type is a ssigned, w hile the r esolution in {@code L2} happen s | |
174 | * when th e {@code i nvokevirtu al} instru ction is l inked. | |
175 | * <p> | |
176 | * Apart f rom the ch ecking of type descr iptors, | |
177 | * a metho d handle's capabilit y to call its underl ying metho d is unres tricted. | |
178 | * If a me thod handl e is forme d on a non -public me thod by a class | |
179 | * that ha s access t o that met hod, the r esulting h andle can be used | |
180 | * in any place by a ny caller who receiv es a refer ence to it . | |
181 | * <p> | |
182 | * Unlike with the C ore Reflec tion API, where acce ss is chec ked every time | |
183 | * a refle ctive meth od is invo ked, | |
184 | * method handle acc ess checki ng is perf ormed | |
185 | * <a href ="MethodHa ndles.Look up.html#ac cess">when the metho d handle i s created< /a>. | |
186 | * In the case of {@ code ldc} (see below ), access checking i s performe d as part of linking | |
187 | * the con stant pool entry und erlying th e constant method ha ndle. | |
188 | * <p> | |
189 | * Thus, h andles to non-public methods, or to meth ods in non -public cl asses, | |
190 | * should generally be kept PW . | |
191 | * They sh ould not b e passed t o untruste d code unl ess their use from | |
192 | * the unt rusted cod e would be harmless. | |
193 | * | |
194 | * <h1>Met hod handle creation< /h1> | |
195 | * Java co de can cre ate a meth od handle that direc tly access es | |
196 | * any met hod, const ructor, or field tha t is acces sible to t hat code. | |
197 | * This is done via a reflecti ve, capabi lity-based API calle d | |
198 | * {@link java.lang. invoke.Met hodHandles .Lookup Me thodHandle s.Lookup} | |
199 | * For exa mple, a st atic metho d handle c an be obta ined | |
200 | * from {@ link java. lang.invok e.MethodHa ndles.Look up#findSta tic Lookup .findStati c}. | |
201 | * There a re also co nversion m ethods fro m Core Ref lection AP I objects, | |
202 | * such as {@link ja va.lang.in voke.Metho dHandles.L ookup#unre flect Look up.unrefle ct}. | |
203 | * <p> | |
204 | * Like cl asses and strings, m ethod hand les that c orrespond to accessi ble | |
205 | * fields, methods, and constr uctors can also be r epresented directly | |
206 | * in a cl ass file's constant pool as co nstants to be loaded by {@code ldc} byte codes. | |
207 | * A new t ype of con stant pool entry, {@ code CONST ANT_Method Handle}, | |
208 | * refers directly t o an assoc iated {@co de CONSTAN T_Methodre f}, | |
209 | * {@code CONSTANT_I nterfaceMe thodref}, or {@code CONSTANT_F ieldref} | |
210 | * constan t pool ent ry. | |
211 | * (For fu ll details on method handle co nstants, | |
212 | * see sec tions 4.4. 8 and 5.4. 3.5 of the Java Virt ual Machin e Specific ation.) | |
213 | * <p> | |
214 | * Method handles pr oduced by lookups or constant loads from methods o r | |
215 | * constru ctors with the varia ble arity modifier b it ({@code 0x0080}) | |
216 | * have a correspond ing variab le arity, as if they were defi ned with | |
217 | * the hel p of {@lin k #asVarar gsCollecto r asVararg sCollector }. | |
218 | * <p> | |
219 | * A metho d referenc e may refe r either t o a static or non-st atic metho d. | |
220 | * In the non-static case, the method ha ndle type includes a n explicit | |
221 | * receive r argument , prepende d before a ny other a rguments. | |
222 | * In the method han dle's type , the init ial receiv er argumen t is typed | |
223 | * accordi ng to the class unde r which th e method w as initial ly request ed. | |
224 | * (E.g., if a non-s tatic meth od handle is obtaine d via {@co de ldc}, | |
225 | * the typ e of the r eceiver is the class named in the consta nt pool en try.) | |
226 | * <p> | |
227 | * Method handle con stants are subject t o the same link-time access ch ecks | |
228 | * their c orrespondi ng bytecod e instruct ions, and the {@code ldc} inst ruction | |
229 | * will th row corres ponding li nkage erro rs if the bytecode b ehaviors w ould | |
230 | * throw s uch errors . | |
231 | * <p> | |
232 | * As a co rollary of this, acc ess to pro tected mem bers is re stricted | |
233 | * to rece ivers only of the ac cessing cl ass, or on e of its s ubclasses, | |
234 | * and the accessing class mus t in turn be a subcl ass (or pa ckage sibl ing) | |
235 | * of the protected member's d efining cl ass. | |
236 | * If a me thod refer ence refer s to a pro tected non -static me thod or fi eld | |
237 | * of a cl ass outsid e the curr ent packag e, the rec eiver argu ment will | |
238 | * be narr owed to th e type of the access ing class. | |
239 | * <p> | |
240 | * When a method han dle to a v irtual met hod is inv oked, the method is | |
241 | * always looked up in the rec eiver (tha t is, the first argu ment). | |
242 | * <p> | |
243 | * A non-v irtual met hod handle to a spec ific virtu al method implementa tion | |
244 | * can als o be creat ed. These do not pe rform virt ual lookup based on | |
245 | * receive r type. S uch a meth od handle simulates the effect of | |
246 | * an {@co de invokes pecial} in struction to the sam e method. | |
247 | * | |
248 | * <h1>Usa ge example s</h1> | |
249 | * Here ar e some exa mples of u sage: | |
250 | * <blockq uote><pre> {@code | |
251 | Object x, y; String s; int i; | |
252 | MethodType mt; Metho dHandle mh ; | |
253 | MethodHand les.Lookup lookup = MethodHand les.lookup (); | |
254 | // mt is ( char,char) String | |
255 | mt = Metho dType.meth odType(Str ing.class, char.clas s, char.cl ass); | |
256 | mh = looku p.findVirt ual(String .class, "r eplace", m t); | |
257 | s = (Strin g) mh.invo keExact("d addy",'d', 'n'); | |
258 | // invokeE xact(Ljava /lang/Stri ng;CC)Ljav a/lang/Str ing; | |
259 | assertEqua ls(s, "nan ny"); | |
260 | // weakly typed invo cation (us ing MHs.in voke) | |
261 | s = (Strin g) mh.invo keWithArgu ments("sap py", 'p', 'v'); | |
262 | assertEqua ls(s, "sav vy"); | |
263 | // mt is ( Object[])L ist | |
264 | mt = Metho dType.meth odType(jav a.util.Lis t.class, O bject[].cl ass); | |
265 | mh = looku p.findStat ic(java.ut il.Arrays. class, "as List", mt) ; | |
266 | assert(mh. isVarargsC ollector() ); | |
267 | x = mh.inv oke("one", "two"); | |
268 | // invoke( Ljava/lang /String;Lj ava/lang/S tring;)Lja va/lang/Ob ject; | |
269 | assertEqua ls(x, java .util.Arra ys.asList( "one","two ")); | |
270 | // mt is ( Object,Obj ect,Object )Object | |
271 | mt = Metho dType.gene ricMethodT ype(3); | |
272 | mh = mh.as Type(mt); | |
273 | x = mh.inv okeExact(( Object)1, (Object)2, (Object)3 ); | |
274 | // invokeE xact(Ljava /lang/Obje ct;Ljava/l ang/Object ;Ljava/lan g/Object;) Ljava/lang /Object; | |
275 | assertEqua ls(x, java .util.Arra ys.asList( 1,2,3)); | |
276 | // mt is ( )int | |
277 | mt = Metho dType.meth odType(int .class); | |
278 | mh = looku p.findVirt ual(java.u til.List.c lass, "siz e", mt); | |
279 | i = (int) mh.invokeE xact(java. util.Array s.asList(1 ,2,3)); | |
280 | // invokeE xact(Ljava /util/List ;)I | |
281 | assert(i = = 3); | |
282 | mt = Metho dType.meth odType(voi d.class, S tring.clas s); | |
283 | mh = looku p.findVirt ual(java.i o.PrintStr eam.class, "println" , mt); | |
284 | mh.invokeE xact(Syste m.out, "He llo, world ."); | |
285 | // invokeE xact(Ljava /io/PrintS tream;Ljav a/lang/Str ing;)V | |
286 | * }</pre> </blockquo te> | |
287 | * Each of the above calls to {@code inv okeExact} or plain { @code invo ke} | |
288 | * generat es a singl e invokevi rtual inst ruction wi th | |
289 | * the sym bolic type descripto r indicate d in the f ollowing c omment. | |
290 | * In thes e examples , the help er method {@code ass ertEquals} is assume d to | |
291 | * be a me thod which calls {@l ink java.u til.Object s#equals(O bject,Obje ct) Object s.equals} | |
292 | * on its arguments, and asser ts that th e result i s true. | |
293 | * | |
294 | * <h1>Exc eptions</h 1> | |
295 | * The met hods {@cod e invokeEx act} and { @code invo ke} are de clared | |
296 | * to thro w {@link j ava.lang.T hrowable T hrowable}, | |
297 | * which i s to say t hat there is no stat ic restric tion on wh at a metho d handle | |
298 | * can thr ow. Since the JVM d oes not di stinguish between ch ecked | |
299 | * and unc hecked exc eptions (o ther than by their c lass, of c ourse), | |
300 | * there i s no parti cular effe ct on byte code shape from ascr ibing | |
301 | * checked exception s to metho d handle i nvocations . But in Java sourc e | |
302 | * code, m ethods whi ch perform method ha ndle calls must eith er explici tly | |
303 | * throw { @code Thro wable}, or else must catch all | |
304 | * throwab les locall y, rethrow ing only t hose which are legal in the co ntext, | |
305 | * and wra pping ones which are illegal. | |
306 | * | |
307 | * <h1><a name="sigp oly"></a>S ignature p olymorphis m</h1> | |
308 | * The unu sual compi lation and linkage b ehavior of | |
309 | * {@code invokeExac t} and pla in {@code invoke} | |
310 | * is refe renced by the term < em>signatu re polymor phism</em> . | |
311 | * As defi ned in the Java Lang uage Speci fication, | |
312 | * a signa ture polym orphic met hod is one which can operate w ith | |
313 | * any of a wide ran ge of call signature s and retu rn types. | |
314 | * <p> | |
315 | * In sour ce code, a call to a signature polymorph ic method will | |
316 | * compile , regardle ss of the requested symbolic t ype descri ptor. | |
317 | * As usua l, the Jav a compiler emits an {@code inv okevirtual } | |
318 | * instruc tion with the given symbolic t ype descri ptor again st the nam ed method. | |
319 | * The unu sual part is that th e symbolic type desc riptor is derived fr om | |
320 | * the act ual argume nt and ret urn types, not from the method declarati on. | |
321 | * <p> | |
322 | * When th e JVM proc esses byte code conta ining sign ature poly morphic ca lls, | |
323 | * it will successfu lly link a ny such ca ll, regard less of it s symbolic type desc riptor. | |
324 | * (In ord er to reta in type sa fety, the JVM will g uard such calls with suitable | |
325 | * dynamic type chec ks, as des cribed els ewhere.) | |
326 | * <p> | |
327 | * Bytecod e generato rs, includ ing the co mpiler bac k end, are required to emit | |
328 | * untrans formed sym bolic type descripto rs for the se methods . | |
329 | * Tools w hich deter mine symbo lic linkag e are requ ired to ac cept such | |
330 | * untrans formed des criptors, without re porting li nkage erro rs. | |
331 | * | |
332 | * <h1>Int eroperatio n between method han dles and t he Core Re flection A PI</h1> | |
333 | * Using f actory met hods in th e {@link j ava.lang.i nvoke.Meth odHandles. Lookup Loo kup} API, | |
334 | * any cla ss member represente d by a Cor e Reflecti on API obj ect | |
335 | * can be converted to a behav iorally eq uivalent m ethod hand le. | |
336 | * For exa mple, a re flective { @link java .lang.refl ect.Method Method} c an | |
337 | * be conv erted to a method ha ndle using | |
338 | * {@link java.lang. invoke.Met hodHandles .Lookup#un reflect Lo okup.unref lect}. | |
339 | * The res ulting met hod handle s generall y provide more direc t and effi cient | |
340 | * access to the und erlying cl ass member s. | |
341 | * <p> | |
342 | * As a sp ecial case , | |
343 | * when th e Core Ref lection AP I is used to view th e signatur e polymorp hic | |
344 | * methods {@code in vokeExact} or plain {@code inv oke} in th is class, | |
345 | * they ap pear as or dinary non -polymorph ic methods . | |
346 | * Their r eflective appearance , as viewe d by | |
347 | * {@link java.lang. Class#getD eclaredMet hod Class. getDeclare dMethod}, | |
348 | * is unaf fected by their spec ial status in this A PI. | |
349 | * For exa mple, {@li nk java.la ng.reflect .Method#ge tModifiers Method.ge tModifiers } | |
350 | * will re port exact ly those m odifier bi ts require d for any similarly | |
351 | * declare d method, including in this ca se {@code native} an d {@code v arargs} bi ts. | |
352 | * <p> | |
353 | * As with any refle cted metho d, these m ethods (wh en reflect ed) may be | |
354 | * invoked via {@lin k java.lan g.reflect. Method#inv oke java.l ang.reflec t.Method.i nvoke}. | |
355 | * However , such ref lective ca lls do not result in method ha ndle invoc ations. | |
356 | * Such a call, if p assed the required a rgument | |
357 | * (a sing le one, of type {@co de Object[ ]}), will ignore the argument and | |
358 | * will th row an {@c ode Unsupp ortedOpera tionExcept ion}. | |
359 | * <p> | |
360 | * Since { @code invo kevirtual} instructi ons can na tively | |
361 | * invoke method han dles under any symbo lic type d escriptor, this refl ective vie w conflict s | |
362 | * with th e normal p resentatio n of these methods v ia bytecod es. | |
363 | * Thus, t hese two n ative meth ods, when reflective ly viewed by | |
364 | * {@code Class.getD eclaredMet hod}, may be regarde d as place holders on ly. | |
365 | * <p> | |
366 | * In orde r to obtai n an invok er method for a part icular typ e descript or, | |
367 | * use {@l ink java.l ang.invoke .MethodHan dles#exact Invoker Me thodHandle s.exactInv oker}, | |
368 | * or {@li nk java.la ng.invoke. MethodHand les#invoke r MethodHa ndles.invo ker}. | |
369 | * The {@l ink java.l ang.invoke .MethodHan dles.Looku p#findVirt ual Lookup .findVirtu al} | |
370 | * API is also able to return a method h andle | |
371 | * to call {@code in vokeExact} or plain {@code inv oke}, | |
372 | * for any specified type desc riptor . | |
373 | * | |
374 | * <h1>Int eroperatio n between method han dles and J ava generi cs</h1> | |
375 | * A metho d handle c an be obta ined on a method, co nstructor, or field | |
376 | * which i s declared with Java generic t ypes. | |
377 | * As with the Core Reflection API, the type of th e method h andle | |
378 | * will co nstructed from the e rasure of the source -level typ e. | |
379 | * When a method han dle is inv oked, the types of i ts argumen ts | |
380 | * or the return val ue cast ty pe may be generic ty pes or typ e instance s. | |
381 | * If this occurs, t he compile r will rep lace those | |
382 | * types b y their er asures whe n it const ructs the symbolic t ype descri ptor | |
383 | * for the {@code in vokevirtua l} instruc tion. | |
384 | * <p> | |
385 | * Method handles do not repre sent | |
386 | * their f unction-li ke types i n terms of Java para meterized (generic) types, | |
387 | * because there are three mis matches be tween func tion-like types and parameteri zed | |
388 | * Java ty pes. | |
389 | * <ul> | |
390 | * <li>Met hod types range over all possi ble aritie s, | |
391 | * from no arguments to up to the <a hr ef="Method Handle.htm l#maxarity ">maximum number</a> of allowe d argument s. | |
392 | * Generic s are not variadic, and so can not repres ent this.< /li> | |
393 | * <li>Met hod types can specif y argument s of primi tive types , | |
394 | * which J ava generi c types ca nnot range over.</li > | |
395 | * <li>Hig her order functions over metho d handles (combinato rs) are | |
396 | * often g eneric acr oss a wide range of function t ypes, incl uding | |
397 | * those o f multiple arities. It is imp ossible to represent such | |
398 | * generic ity with a Java type parameter .</li> | |
399 | * </ul> | |
400 | * | |
401 | * <h1><a name="maxa rity"></a> Arity limi ts</h1> | |
402 | * The JVM imposes o n all meth ods and co nstructors of any ki nd an abso lute | |
403 | * limit o f 255 stac ked argume nts. This limit can appear mo re restric tive | |
404 | * in cert ain cases: | |
405 | * <ul> | |
406 | * <li>A { @code long } or {@cod e double} argument c ounts (for purposes of arity l imits) as two argume nt slots. | |
407 | * <li>A n on-static method con sumes an e xtra argum ent for th e object o n which th e method i s called. | |
408 | * <li>A c onstructor consumes an extra a rgument fo r the obje ct which i s being co nstructed. | |
409 | * <li>Sin ce a metho d handle&r squo;s {@c ode invoke } method ( or other s ignature-p olymorphic method) i s non-virt ual, | |
410 | * it consumes a n extra ar gument for the metho d handle i tself, in addition t o any non- virtual re ceiver obj ect. | |
411 | * </ul> | |
412 | * These l imits impl y that cer tain metho d handles cannot be created, s olely beca use of the JVM limit on stacke d argument s. | |
413 | * For exa mple, if a static JV M method a ccepts exa ctly 255 a rguments, a method h andle cann ot be crea ted for it . | |
414 | * Attempt s to creat e method h andles wit h impossib le method types lead to an {@l ink Illega lArgumentE xception}. | |
415 | * In part icular, a method han dle’ s type mus t not have an arity of the exa ct maximum 255. | |
416 | * | |
417 | * @see Me thodType | |
418 | * @see Me thodHandle s | |
419 | * @author John Rose , JSR 292 EG | |
420 | */ | |
421 | public abs tract clas s MethodHa ndle { | |
422 | static { MethodH andleImpl. initStatic s(); } | |
423 | ||
424 | /** | |
425 | * Int ernal mark er interfa ce which d istinguish es (to the Java comp iler) | |
426 | * tho se methods which are <a href=" MethodHand le.html#si gpoly">sig nature pol ymorphic</ a>. | |
427 | */ | |
428 | @java. lang.annot ation.Targ et({java.l ang.annota tion.Eleme ntType.MET HOD}) | |
429 | @java. lang.annot ation.Rete ntion(java .lang.anno tation.Ret entionPoli cy.RUNTIME ) | |
430 | @inter face Polym orphicSign ature { } | |
431 | ||
432 | privat e final Me thodType t ype; | |
433 | /*priv ate*/ fina l LambdaFo rm form; | |
434 | // for m is not p rivate so that invok ers can ea sily fetch it | |
435 | /*priv ate*/ Meth odHandle a sTypeCache ; | |
436 | // asT ypeCache i s not priv ate so tha t invokers can easil y fetch it | |
437 | /*non- public*/ b yte custom izationCou nt; | |
438 | // cus tomization Count shou ld be acce ssible fro m invokers | |
439 | ||
440 | /** | |
441 | * Rep orts the t ype of thi s method h andle. | |
442 | * Eve ry invocat ion of thi s method h andle via {@code inv okeExact} must exact ly match t his type. | |
443 | * @re turn the m ethod hand le type | |
444 | */ | |
445 | public MethodTyp e type() { | |
446 | re turn type; | |
447 | } | |
448 | ||
449 | /** | |
450 | * Pac kage-priva te constru ctor for t he method handle imp lementatio n hierarch y. | |
451 | * Met hod handle inheritan ce will be contained completel y within | |
452 | * the {@code ja va.lang.in voke} pack age. | |
453 | */ | |
454 | // @pa ram type t ype (perma nently ass igned) of the new me thod handl e | |
455 | /*non- public*/ M ethodHandl e(MethodTy pe type, L ambdaForm form) { | |
456 | ty pe.getClas s(); // e xplicit NP E | |
457 | fo rm.getClas s(); // e xplicit NP E | |
458 | th is.type = type; | |
459 | th is.form = form.uncus tomize(); | |
460 | ||
461 | th is.form.pr epare(); // TO DO: Try to de lay this s tep until just befor e invocati on. | |
462 | } | |
463 | ||
464 | /** | |
465 | * Inv okes the m ethod hand le, allowi ng any cal ler type d escriptor, but requi ring an ex act type m atch. | |
466 | * The symbolic type descr iptor at t he call si te of {@co de invokeE xact} must | |
467 | * exa ctly match this meth od handle' s {@link # type type} . | |
468 | * No conversion s are allo wed on arg uments or return val ues. | |
469 | * <p> | |
470 | * Whe n this met hod is obs erved via the Core R eflection API, | |
471 | * it will appea r as a sin gle native method, t aking an o bject arra y and retu rning an o bject. | |
472 | * If this nativ e method i s invoked directly v ia | |
473 | * {@l ink java.l ang.reflec t.Method#i nvoke java .lang.refl ect.Method .invoke}, via JNI, | |
474 | * or indirectly via {@lin k java.lan g.invoke.M ethodHandl es.Lookup# unreflect Lookup.unr eflect}, | |
475 | * it will throw an {@code Unsupport edOperatio nException }. | |
476 | * @pa ram args t he signatu re-polymor phic param eter list, staticall y represen ted using varargs | |
477 | * @re turn the s ignature-p olymorphic result, s tatically represente d using {@ code Objec t} | |
478 | * @th rows Wrong MethodType Exception if the tar get's type is not id entical wi th the cal ler's symb olic type descriptor | |
479 | * @th rows Throw able anyth ing thrown by the un derlying m ethod prop agates unc hanged thr ough the m ethod hand le call | |
480 | */ | |
481 | public final nat ive @Polym orphicSign ature Obje ct invokeE xact(Objec t... args) throws Th rowable; | |
482 | ||
483 | /** | |
484 | * Inv okes the m ethod hand le, allowi ng any cal ler type d escriptor, | |
485 | * and optionall y performi ng convers ions on ar guments an d return v alues. | |
486 | * <p> | |
487 | * If the call s ite's symb olic type descriptor exactly m atches thi s method h andle's {@ link #type type}, | |
488 | * the call proc eeds as if by {@link #invokeEx act invoke Exact}. | |
489 | * <p> | |
490 | * Oth erwise, th e call pro ceeds as i f this met hod handle were firs t | |
491 | * adj usted by c alling {@l ink #asTyp e asType} to adjust this metho d handle | |
492 | * to the requir ed type, a nd then th e call pro ceeds as i f by | |
493 | * {@l ink #invok eExact inv okeExact} on the adj usted meth od handle. | |
494 | * <p> | |
495 | * The re is no g uarantee t hat the {@ code asTyp e} call is actually made. | |
496 | * If the JVM ca n predict the result s of makin g the call , it may p erform | |
497 | * ada ptations d irectly on the calle r's argume nts, | |
498 | * and call the target met hod handle according to its ow n exact ty pe. | |
499 | * <p> | |
500 | * The resolved type descr iptor at t he call si te of {@co de invoke} must | |
501 | * be a valid ar gument to the receiv ers {@code asType} m ethod. | |
502 | * In particular , the call er must sp ecify the same argum ent arity | |
503 | * as the callee 's type, | |
504 | * if the callee is not a {@linkplai n #asVarar gsCollecto r variable arity col lector}. | |
505 | * <p> | |
506 | * Whe n this met hod is obs erved via the Core R eflection API, | |
507 | * it will appea r as a sin gle native method, t aking an o bject arra y and retu rning an o bject. | |
508 | * If this nativ e method i s invoked directly v ia | |
509 | * {@l ink java.l ang.reflec t.Method#i nvoke java .lang.refl ect.Method .invoke}, via JNI, | |
510 | * or indirectly via {@lin k java.lan g.invoke.M ethodHandl es.Lookup# unreflect Lookup.unr eflect}, | |
511 | * it will throw an {@code Unsupport edOperatio nException }. | |
512 | * @pa ram args t he signatu re-polymor phic param eter list, staticall y represen ted using varargs | |
513 | * @re turn the s ignature-p olymorphic result, s tatically represente d using {@ code Objec t} | |
514 | * @th rows Wrong MethodType Exception if the tar get's type cannot be adjusted to the cal ler's symb olic type descriptor | |
515 | * @th rows Class CastExcept ion if the target's type can b e adjusted to the ca ller, but a referenc e cast fai ls | |
516 | * @th rows Throw able anyth ing thrown by the un derlying m ethod prop agates unc hanged thr ough the m ethod hand le call | |
517 | */ | |
518 | public final nat ive @Polym orphicSign ature Obje ct invoke( Object... args) thro ws Throwab le; | |
519 | ||
520 | /** | |
521 | * Pri vate metho d for trus ted invoca tion of a method han dle respec ting simpl ified sign atures. | |
522 | * Typ e mismatch es will no t throw {@ code Wrong MethodType Exception} , but coul d crash th e JVM. | |
523 | * <p> | |
524 | * The caller si gnature is restricte d to the f ollowing b asic types : | |
525 | * Obj ect, int, long, floa t, double, and void return. | |
526 | * <p> | |
527 | * The caller is responsib le for mai ntaining t ype correc tness by e nsuring | |
528 | * tha t the each outgoing argument v alue is a member of the range of the cor responding | |
529 | * cal lee argume nt type. | |
530 | * (Th e caller s hould ther efore issu e appropri ate casts and intege r narrowin g | |
531 | * ope rations on outgoing argument v alues.) | |
532 | * The caller ca n assume t hat the in coming res ult value is part of the range | |
533 | * of the callee 's return type. | |
534 | * @pa ram args t he signatu re-polymor phic param eter list, staticall y represen ted using varargs | |
535 | * @re turn the s ignature-p olymorphic result, s tatically represente d using {@ code Objec t} | |
536 | */ | |
537 | /*non- public*/ f inal nativ e @Polymor phicSignat ure Object invokeBas ic(Object. .. args) t hrows Thro wable; | |
538 | ||
539 | /** | |
540 | * Pri vate metho d for trus ted invoca tion of a MemberName of kind { @code REF_ invokeVirt ual}. | |
541 | * The caller si gnature is restricte d to basic types as with {@cod e invokeBa sic}. | |
542 | * The trailing (not leadi ng) argume nt must be a MemberN ame. | |
543 | * @pa ram args t he signatu re-polymor phic param eter list, staticall y represen ted using varargs | |
544 | * @re turn the s ignature-p olymorphic result, s tatically represente d using {@ code Objec t} | |
545 | */ | |
546 | /*non- public*/ s tatic nati ve @Polymo rphicSigna ture Objec t linkToVi rtual(Obje ct... args ) throws T hrowable; | |
547 | ||
548 | /** | |
549 | * Pri vate metho d for trus ted invoca tion of a MemberName of kind { @code REF_ invokeStat ic}. | |
550 | * The caller si gnature is restricte d to basic types as with {@cod e invokeBa sic}. | |
551 | * The trailing (not leadi ng) argume nt must be a MemberN ame. | |
552 | * @pa ram args t he signatu re-polymor phic param eter list, staticall y represen ted using varargs | |
553 | * @re turn the s ignature-p olymorphic result, s tatically represente d using {@ code Objec t} | |
554 | */ | |
555 | /*non- public*/ s tatic nati ve @Polymo rphicSigna ture Objec t linkToSt atic(Objec t... args) throws Th rowable; | |
556 | ||
557 | /** | |
558 | * Pri vate metho d for trus ted invoca tion of a MemberName of kind { @code REF_ invokeSpec ial}. | |
559 | * The caller si gnature is restricte d to basic types as with {@cod e invokeBa sic}. | |
560 | * The trailing (not leadi ng) argume nt must be a MemberN ame. | |
561 | * @pa ram args t he signatu re-polymor phic param eter list, staticall y represen ted using varargs | |
562 | * @re turn the s ignature-p olymorphic result, s tatically represente d using {@ code Objec t} | |
563 | */ | |
564 | /*non- public*/ s tatic nati ve @Polymo rphicSigna ture Objec t linkToSp ecial(Obje ct... args ) throws T hrowable; | |
565 | ||
566 | /** | |
567 | * Pri vate metho d for trus ted invoca tion of a MemberName of kind { @code REF_ invokeInte rface}. | |
568 | * The caller si gnature is restricte d to basic types as with {@cod e invokeBa sic}. | |
569 | * The trailing (not leadi ng) argume nt must be a MemberN ame. | |
570 | * @pa ram args t he signatu re-polymor phic param eter list, staticall y represen ted using varargs | |
571 | * @re turn the s ignature-p olymorphic result, s tatically represente d using {@ code Objec t} | |
572 | */ | |
573 | /*non- public*/ s tatic nati ve @Polymo rphicSigna ture Objec t linkToIn terface(Ob ject... ar gs) throws Throwable ; | |
574 | ||
575 | /** | |
576 | * Per forms a va riable ari ty invocat ion, passi ng the arg uments in the given list | |
577 | * to the method handle, a s if via a n inexact {@link #in voke invok e} from a call site | |
578 | * whi ch mention s only the type {@co de Object} , and whos e arity is the lengt h | |
579 | * of the argume nt list. | |
580 | * <p> | |
581 | * Spe cifically, execution proceeds as if by t he followi ng steps, | |
582 | * alt hough the methods ar e not guar anteed to be called if the JVM | |
583 | * can predict t heir effec ts. | |
584 | * <ul > | |
585 | * <li >Determine the lengt h of the a rgument ar ray as {@c ode N}. | |
586 | * For a nul l referenc e, {@code N=0}. </li > | |
587 | * <li >Determine the gener al type {@ code TN} o f {@code N } argument s as | |
588 | * as {@code TN=Method Type.gener icMethodTy pe(N)}.</l i> | |
589 | * <li >Force the original target met hod handle {@code MH 0} to the | |
590 | * required type, as { @code MH1 = MH0.asTy pe(TN)}. < /li> | |
591 | * <li >Spread th e array in to {@code N} separat e argument s {@code A 0, ...}. < /li> | |
592 | * <li >Invoke th e type-adj usted meth od handle on the unp acked argu ments: | |
593 | * MH1.invok eExact(A0, ...). </l i> | |
594 | * <li >Take the return val ue as an { @code Obje ct} refere nce. </li> | |
595 | * </u l> | |
596 | * <p> | |
597 | * Bec ause of th e action o f the {@co de asType} step, the following argument | |
598 | * con versions a re applied as necess ary: | |
599 | * <ul > | |
600 | * <li >reference casting | |
601 | * <li >unboxing | |
602 | * <li >widening primitive conversion s | |
603 | * </u l> | |
604 | * <p> | |
605 | * The result re turned by the call i s boxed if it is a p rimitive, | |
606 | * or forced to null if th e return t ype is voi d. | |
607 | * <p> | |
608 | * Thi s call is equivalent to the fo llowing co de: | |
609 | * <bl ockquote>< pre>{@code | |
610 | * Met hodHandle invoker = MethodHand les.spread Invoker(th is.type(), 0); | |
611 | * Obj ect result = invoker .invokeExa ct(this, a rguments); | |
612 | * }</ pre></bloc kquote> | |
613 | * <p> | |
614 | * Unl ike the si gnature po lymorphic methods {@ code invok eExact} an d {@code i nvoke}, | |
615 | * {@c ode invoke WithArgume nts} can b e accessed normally via the Co re Reflect ion API an d JNI. | |
616 | * It can theref ore be use d as a bri dge betwee n native o r reflecti ve code an d method h andles. | |
617 | * | |
618 | * @pa ram argume nts the ar guments to pass to t he target | |
619 | * @re turn the r esult retu rned by th e target | |
620 | * @th rows Class CastExcept ion if an argument c annot be c onverted b y referenc e casting | |
621 | * @th rows Wrong MethodType Exception if the tar get's type cannot be adjusted to take th e given nu mber of {@ code Objec t} argumen ts | |
622 | * @th rows Throw able anyth ing thrown by the ta rget metho d invocati on | |
623 | * @se e MethodHa ndles#spre adInvoker | |
624 | */ | |
625 | public Object in vokeWithAr guments(Ob ject... ar guments) t hrows Thro wable { | |
626 | Me thodType i nvocationT ype = Meth odType.gen ericMethod Type(argum ents == nu ll ? 0 : a rguments.l ength); | |
627 | re turn invoc ationType. invokers() .spreadInv oker(0).in vokeExact( asType(inv ocationTyp e), argume nts); | |
628 | } | |
629 | ||
630 | /** | |
631 | * Per forms a va riable ari ty invocat ion, passi ng the arg uments in the given array | |
632 | * to the method handle, a s if via a n inexact {@link #in voke invok e} from a call site | |
633 | * whi ch mention s only the type {@co de Object} , and whos e arity is the lengt h | |
634 | * of the argume nt array. | |
635 | * <p> | |
636 | * Thi s method i s also equ ivalent to the follo wing code: | |
637 | * <bl ockquote>< pre>{@code | |
638 | * i nvokeWithA rguments(a rguments.t oArray() | |
639 | * }</ pre></bloc kquote> | |
640 | * | |
641 | * @pa ram argume nts the ar guments to pass to t he target | |
642 | * @re turn the r esult retu rned by th e target | |
643 | * @th rows NullP ointerExce ption if { @code argu ments} is a null ref erence | |
644 | * @th rows Class CastExcept ion if an argument c annot be c onverted b y referenc e casting | |
645 | * @th rows Wrong MethodType Exception if the tar get's type cannot be adjusted to take th e given nu mber of {@ code Objec t} argumen ts | |
646 | * @th rows Throw able anyth ing thrown by the ta rget metho d invocati on | |
647 | */ | |
648 | public Object in vokeWithAr guments(ja va.util.Li st<?> argu ments) thr ows Throwa ble { | |
649 | re turn invok eWithArgum ents(argum ents.toArr ay()); | |
650 | } | |
651 | ||
652 | /** | |
653 | * Pro duces an a dapter met hod handle which ada pts the ty pe of the | |
654 | * cur rent metho d handle t o a new ty pe. | |
655 | * The resulting method ha ndle is gu aranteed t o report a type | |
656 | * whi ch is equa l to the d esired new type. | |
657 | * <p> | |
658 | * If the origin al type an d new type are equal , returns {@code thi s}. | |
659 | * <p> | |
660 | * The new metho d handle, when invok ed, will p erform the following | |
661 | * ste ps: | |
662 | * <ul > | |
663 | * <li >Convert t he incomin g argument list to m atch the o riginal | |
664 | * method ha ndle's arg ument list . | |
665 | * <li >Invoke th e original method ha ndle on th e converte d argument list. | |
666 | * <li >Convert a ny result returned b y the orig inal metho d handle | |
667 | * to the re turn type of new met hod handle . | |
668 | * </u l> | |
669 | * <p> | |
670 | * Thi s method p rovides th e crucial behavioral differenc e between | |
671 | * {@l ink #invok eExact inv okeExact} and plain, inexact { @link #inv oke invoke }. | |
672 | * The two metho ds | |
673 | * per form the s ame steps when the c aller's ty pe descrip tor exactl y m atches | |
674 | * the callee's, but when the types differ, pl ain {@link #invoke i nvoke} | |
675 | * als o calls {@ code asTyp e} (or som e internal equivalen t) in orde r | |
676 | * to match up t he caller' s and call ee's types . | |
677 | * <p> | |
678 | * If the curren t method i s a variab le arity m ethod hand le | |
679 | * arg ument list conversio n may invo lve the co nversion a nd collect ion | |
680 | * of several ar guments in to an arra y, as | |
681 | * {@l inkplain # asVarargsC ollector d escribed e lsewhere}. | |
682 | * In every othe r case, al l conversi ons are ap plied <em> pairwise</ em>, | |
683 | * whi ch means t hat each a rgument or return va lue is con verted to | |
684 | * exa ctly one a rgument or return va lue (or no return va lue). | |
685 | * The applied c onversions are defin ed by cons ulting the | |
686 | * the correspon ding compo nent types of the ol d and new | |
687 | * met hod handle types. | |
688 | * <p> | |
689 | * Let <em>T0</e m> and <em >T1</em> b e correspo nding new and old pa rameter ty pes, | |
690 | * or old and ne w return t ypes. Spe cifically, for some valid inde x {@code i }, let | |
691 | * <em >T0</em>{@ code =newT ype.parame terType(i) } and <em> T1</em>{@c ode =this. type().par ameterType (i)}. | |
692 | * Or else, goin g the othe r way for return val ues, let | |
693 | * <em >T0</em>{@ code =this .type().re turnType() } and <em> T1</em>{@c ode =newTy pe.returnT ype()}. | |
694 | * If the types are the sa me, the ne w method h andle make s no chang e | |
695 | * to the corres ponding ar gument or return val ue (if any ). | |
696 | * Oth erwise, on e of the f ollowing c onversions is applie d | |
697 | * if possible: | |
698 | * <ul > | |
699 | * <li >If <em>T0 </em> and <em>T1</em > are refe rences, th en a cast to <em>T1< /em> is ap plied. | |
700 | * (The type s do not n eed to be related in any parti cular way. | |
701 | * This is b ecause a d ynamic val ue of null can conve rt to any reference type.) | |
702 | * <li >If <em>T0 </em> and <em>T1</em > are prim itives, th en a Java method inv ocation | |
703 | * conversio n (JLS 5.3 ) is appli ed, if one exists. | |
704 | * (Specific ally, <em> T0</em> mu st convert to <em>T1 </em> by a widening primitive conversion .) | |
705 | * <li >If <em>T0 </em> is a primitive and <em>T 1</em> a r eference, | |
706 | * a Java ca sting conv ersion (JL S 5.5) is applied if one exist s. | |
707 | * (Specific ally, the value is b oxed from <em>T0</em > to its w rapper cla ss, | |
708 | * which is then widen ed as need ed to <em> T1</em>.) | |
709 | * <li >If <em>T0 </em> is a reference and <em>T 1</em> a p rimitive, an unboxin g | |
710 | * conversio n will be applied at runtime, possibly f ollowed | |
711 | * by a Java method in vocation c onversion (JLS 5.3) | |
712 | * on the pr imitive va lue. (The se are the primitive widening conversion s.) | |
713 | * <em>T0</e m> must be a wrapper class or a supertyp e of one. | |
714 | * (In the c ase where <em>T0</em > is Objec t, these a re the con versions | |
715 | * allowed b y {@link j ava.lang.r eflect.Met hod#invoke java.lang .reflect.M ethod.invo ke}.) | |
716 | * The unbox ing conver sion must have a pos sibility o f success, which mea ns that | |
717 | * if <em>T0 </em> is n ot itself a wrapper class, the re must ex ist at lea st one | |
718 | * wrapper c lass <em>T W</em> whi ch is a su btype of < em>T0</em> and whose unboxed | |
719 | * primitive value can be widene d to <em>T 1</em>. | |
720 | * <li >If the re turn type <em>T1</em > is marke d as void, any retur ned value is discard ed | |
721 | * <li >If the re turn type <em>T0</em > is void and <em>T1 </em> a re ference, a null valu e is intro duced. | |
722 | * <li >If the re turn type <em>T0</em > is void and <em>T1 </em> a pr imitive, | |
723 | * a zero va lue is int roduced. | |
724 | * </u l> | |
725 | * (<e m>Note:</e m> Both <e m>T0</em> and <em>T1 </em> may be regarde d as stati c types, | |
726 | * bec ause neith er corresp onds speci fically to the <em>d ynamic typ e</em> of any | |
727 | * act ual argume nt or retu rn value.) | |
728 | * <p> | |
729 | * The method ha ndle conve rsion cann ot be made if any on e of the r equired | |
730 | * pai rwise conv ersions ca nnot be ma de. | |
731 | * <p> | |
732 | * At runtime, t he convers ions appli ed to refe rence argu ments | |
733 | * or return val ues may re quire addi tional run time check s which ca n fail. | |
734 | * An unboxing o peration m ay fail be cause the original r eference i s null, | |
735 | * cau sing a {@l ink java.l ang.NullPo interExcep tion NullP ointerExce ption}. | |
736 | * An unboxing o peration o r a refere nce cast m ay also fa il on a re ference | |
737 | * to an object of the wro ng type, | |
738 | * cau sing a {@l ink java.l ang.ClassC astExcepti on ClassCa stExceptio n}. | |
739 | * Alt hough an u nboxing op eration ma y accept s everal kin ds of wrap pers, | |
740 | * if none are a vailable, a {@code C lassCastEx ception} w ill be thr own. | |
741 | * | |
742 | * @pa ram newTyp e the expe cted type of the new method ha ndle | |
743 | * @re turn a met hod handle which del egates to {@code thi s} after p erforming | |
744 | * any necessary argument conversion s, and arr anges for any | |
745 | * nec essary ret urn value conversion s | |
746 | * @th rows NullP ointerExce ption if { @code newT ype} is a null refer ence | |
747 | * @th rows Wrong MethodType Exception if the con version ca nnot be ma de | |
748 | * @se e MethodHa ndles#expl icitCastAr guments | |
749 | */ | |
750 | public MethodHan dle asType (MethodTyp e newType) { | |
751 | // Fast path alternati ve to a he avyweight {@code asT ype} call. | |
752 | // Return 't his' if th e conversi on will be a no-op. | |
753 | if (newType == type) { | |
754 | return t his; | |
755 | } | |
756 | // Return 't his.asType Cache' if the conver sion is al ready memo ized. | |
757 | Me thodHandle atc = asT ypeCached( newType); | |
758 | if (atc != n ull) { | |
759 | return a tc; | |
760 | } | |
761 | re turn asTyp eUncached( newType); | |
762 | } | |
763 | ||
764 | privat e MethodHa ndle asTyp eCached(Me thodType n ewType) { | |
765 | Me thodHandle atc = asT ypeCache; | |
766 | if (atc != n ull && new Type == at c.type) { | |
767 | return a tc; | |
768 | } | |
769 | re turn null; | |
770 | } | |
771 | ||
772 | /** Ov erride thi s to chang e asType b ehavior. * / | |
773 | /*non- public*/ M ethodHandl e asTypeUn cached(Met hodType ne wType) { | |
774 | if (!type.is Convertibl eTo(newTyp e)) | |
775 | throw ne w WrongMet hodTypeExc eption("ca nnot conve rt "+this+ " to "+new Type); | |
776 | re turn asTyp eCache = M ethodHandl eImpl.make PairwiseCo nvert(this , newType, true); | |
777 | } | |
778 | ||
779 | /** | |
780 | * Mak es an <em> array-spre ading</em> method ha ndle, whic h accepts a trailing array arg ument | |
781 | * and spreads i ts element s as posit ional argu ments. | |
782 | * The new metho d handle a dapts, as its <i>tar get</i>, | |
783 | * the current m ethod hand le. The t ype of the adapter w ill be | |
784 | * the same as t he type of the targe t, except that the f inal | |
785 | * {@c ode arrayL ength} par ameters of the targe t's type a re replace d | |
786 | * by a single a rray param eter of ty pe {@code arrayType} . | |
787 | * <p> | |
788 | * If the array element ty pe differs from any of the cor responding | |
789 | * arg ument type s on the o riginal ta rget, | |
790 | * the original target is adapted to take the array elem ents direc tly, | |
791 | * as if by a ca ll to {@li nk #asType asType}. | |
792 | * <p> | |
793 | * Whe n called, the adapte r replaces a trailin g array ar gument | |
794 | * by the array' s elements , each as its own ar gument to the target . | |
795 | * (Th e order of the argum ents is pr eserved.) | |
796 | * The y are conv erted pair wise by ca sting and/ or unboxin g | |
797 | * to the types of the tra iling para meters of the target . | |
798 | * Fin ally the t arget is c alled. | |
799 | * Wha t the targ et eventua lly return s is retur ned unchan ged by the adapter. | |
800 | * <p> | |
801 | * Bef ore callin g the targ et, the ad apter veri fies that the array | |
802 | * con tains exac tly enough elements to provide a correct argument count | |
803 | * to the target method ha ndle. | |
804 | * (Th e array ma y also be null when zero eleme nts are re quired.) | |
805 | * <p> | |
806 | * If, when the adapter is called, t he supplie d array ar gument doe s | |
807 | * not have the correct nu mber of el ements, th e adapter will throw | |
808 | * an {@link Ill egalArgume ntExceptio n} instead of invoki ng the tar get. | |
809 | * <p> | |
810 | * Her e are some simple ex amples of array-spre ading meth od handles : | |
811 | * <bl ockquote>< pre>{@code | |
812 | MethodHand le equals = publicLo okup() | |
813 | .findVir tual(Strin g.class, " equals", m ethodType( boolean.cl ass, Objec t.class)); | |
814 | assert( (b oolean) eq uals.invok eExact("me ", (Object )"me")); | |
815 | assert(!(b oolean) eq uals.invok eExact("me ", (Object )"thee")); | |
816 | // spread both argum ents from a 2-array: | |
817 | MethodHand le eq2 = e quals.asSp reader(Obj ect[].clas s, 2); | |
818 | assert( (b oolean) eq 2.invokeEx act(new Ob ject[]{ "m e", "me" } )); | |
819 | assert(!(b oolean) eq 2.invokeEx act(new Ob ject[]{ "m e", "thee" })); | |
820 | // try to spread fro m anything but a 2-a rray: | |
821 | for (int n = 0; n <= 10; n++) { | |
822 | Object[] badArityA rgs = (n = = 2 ? null : new Obj ect[n]); | |
823 | try { as sert((bool ean) eq2.i nvokeExact (badArityA rgs) && fa lse); } | |
824 | catch (I llegalArgu mentExcept ion ex) { } // OK | |
825 | } | |
826 | // spread both argum ents from a String a rray: | |
827 | MethodHand le eq2s = equals.asS preader(St ring[].cla ss, 2); | |
828 | assert( (b oolean) eq 2s.invokeE xact(new S tring[]{ " me", "me" })); | |
829 | assert(!(b oolean) eq 2s.invokeE xact(new S tring[]{ " me", "thee " })); | |
830 | // spread second arg uments fro m a 1-arra y: | |
831 | MethodHand le eq1 = e quals.asSp reader(Obj ect[].clas s, 1); | |
832 | assert( (b oolean) eq 1.invokeEx act("me", new Object []{ "me" } )); | |
833 | assert(!(b oolean) eq 1.invokeEx act("me", new Object []{ "thee" })); | |
834 | // spread no argumen ts from a 0-array or null: | |
835 | MethodHand le eq0 = e quals.asSp reader(Obj ect[].clas s, 0); | |
836 | assert( (b oolean) eq 0.invokeEx act("me", (Object)"m e", new Ob ject[0])); | |
837 | assert(!(b oolean) eq 0.invokeEx act("me", (Object)"t hee", (Obj ect[])null )); | |
838 | // asSprea der and as Collector are approx imate inve rses: | |
839 | for (int n = 0; n <= 2; n++) { | |
840 | for (C lass<?> a : new Clas s<?>[]{Obj ect[].clas s, String[ ].class, C harSequenc e[].class} ) { | |
841 | Me thodHandle equals2 = equals.as Spreader(a , n).asCol lector(a, n); | |
842 | as sert( (boo lean) equa ls2.invoke WithArgume nts("me", "me")); | |
843 | as sert(!(boo lean) equa ls2.invoke WithArgume nts("me", "thee")); | |
844 | } | |
845 | } | |
846 | MethodHand le caToStr ing = publ icLookup() | |
847 | .findSta tic(Arrays .class, "t oString", methodType (String.cl ass, char[ ].class)); | |
848 | assertEqua ls("[A, B, C]", (Str ing) caToS tring.invo keExact("A BC".toChar Array())); | |
849 | MethodHand le caStrin g3 = caToS tring.asCo llector(ch ar[].class , 3); | |
850 | assertEqua ls("[A, B, C]", (Str ing) caStr ing3.invok eExact('A' , 'B', 'C' )); | |
851 | MethodHand le caToStr ing2 = caS tring3.asS preader(ch ar[].class , 2); | |
852 | assertEqua ls("[A, B, C]", (Str ing) caToS tring2.inv okeExact(' A', "BC".t oCharArray ())); | |
853 | * }</ pre></bloc kquote> | |
854 | * @pa ram arrayT ype usuall y {@code O bject[]}, the type o f the arra y argument from whic h to extra ct the spr ead argume nts | |
855 | * @pa ram arrayL ength the number of arguments to spread from an in coming arr ay argumen t | |
856 | * @re turn a new method ha ndle which spreads i ts final a rray argum ent, | |
857 | * befor e calling the origin al method handle | |
858 | * @th rows NullP ointerExce ption if { @code arra yType} is a null ref erence | |
859 | * @th rows Illeg alArgument Exception if {@code arrayType} is not an array typ e, | |
860 | * or if target do es not hav e at least | |
861 | * {@cod e arrayLen gth} param eter types , | |
862 | * or if {@code ar rayLength} is negati ve, | |
863 | * or if the resul ting metho d handle's type woul d have | |
864 | * <a hr ef="Method Handle.htm l#maxarity ">too many parameter s</a> | |
865 | * @th rows Wrong MethodType Exception if the imp lied {@cod e asType} call fails | |
866 | * @se e #asColle ctor | |
867 | */ | |
868 | public MethodHan dle asSpre ader(Class <?> arrayT ype, int a rrayLength ) { | |
869 | Me thodType p ostSpreadT ype = asSp readerChec ks(arrayTy pe, arrayL ength); | |
870 | in t arity = type().par ameterCoun t(); | |
871 | in t spreadAr gPos = ari ty - array Length; | |
872 | Me thodHandle afterSpre ad = this. asType(pos tSpreadTyp e); | |
873 | Bo undMethodH andle mh = afterSpre ad.rebind( ); | |
874 | La mbdaForm l form = mh. editor().s preadArgum entsForm(1 + spreadA rgPos, arr ayType, ar rayLength) ; | |
875 | Me thodType p reSpreadTy pe = postS preadType. replacePar ameterType s(spreadAr gPos, arit y, arrayTy pe); | |
876 | re turn mh.co pyWith(pre SpreadType , lform); | |
877 | } | |
878 | ||
879 | /** | |
880 | * See if {@code asSpreade r} can be validly ca lled with the given arguments. | |
881 | * Ret urn the ty pe of the method han dle call a fter sprea ding but b efore conv ersions. | |
882 | */ | |
883 | privat e MethodTy pe asSprea derChecks( Class<?> a rrayType, int arrayL ength) { | |
884 | sp readArrayC hecks(arra yType, arr ayLength); | |
885 | in t nargs = type().par ameterCoun t(); | |
886 | if (nargs < arrayLengt h || array Length < 0 ) | |
887 | throw ne wIllegalAr gumentExce ption("bad spread ar ray length "); | |
888 | Cl ass<?> arr ayElement = arrayTyp e.getCompo nentType() ; | |
889 | Me thodType m type = typ e(); | |
890 | bo olean matc h = true, fail = fal se; | |
891 | fo r (int i = nargs - a rrayLength ; i < narg s; i++) { | |
892 | Class<?> ptype = m type.param eterType(i ); | |
893 | if (ptyp e != array Element) { | |
894 | matc h = false; | |
895 | if ( !MethodTyp e.canConve rt(arrayEl ement, pty pe)) { | |
896 | fail = tru e; | |
897 | break; | |
898 | } | |
899 | } | |
900 | } | |
901 | if (match) return mty pe; | |
902 | Me thodType n eedType = mtype.asSp readerType (arrayType , arrayLen gth); | |
903 | if (!fail) return nee dType; | |
904 | // elicit an error: | |
905 | th is.asType( needType); | |
906 | th row newInt ernalError ("should n ot return" , null); | |
907 | } | |
908 | ||
909 | privat e void spr eadArrayCh ecks(Class <?> arrayT ype, int a rrayLength ) { | |
910 | Cl ass<?> arr ayElement = arrayTyp e.getCompo nentType() ; | |
911 | if (arrayEle ment == nu ll) | |
912 | throw ne wIllegalAr gumentExce ption("not an array type", arr ayType); | |
913 | if ((arrayLe ngth & 0x7 F) != arra yLength) { | |
914 | if ((arr ayLength & 0xFF) != arrayLengt h) | |
915 | thro w newIlleg alArgument Exception( "array len gth is not legal", a rrayLength ); | |
916 | assert(a rrayLength >= 128); | |
917 | if (arra yElement = = long.cla ss || | |
918 | arra yElement = = double.c lass) | |
919 | thro w newIlleg alArgument Exception( "array len gth is not legal for long[] or double[]" , arrayLen gth); | |
920 | } | |
921 | } | |
922 | ||
923 | /** | |
924 | * Mak es an <em> array-coll ecting</em > method h andle, whi ch accepts a given n umber of t railing | |
925 | * pos itional ar guments an d collects them into an array argument. | |
926 | * The new metho d handle a dapts, as its <i>tar get</i>, | |
927 | * the current m ethod hand le. The t ype of the adapter w ill be | |
928 | * the same as t he type of the targe t, except that a sin gle traili ng | |
929 | * par ameter (us ually of t ype {@code arrayType }) is repl aced by | |
930 | * {@c ode arrayL ength} par ameters wh ose type i s element type of {@ code array Type}. | |
931 | * <p> | |
932 | * If the array type diffe rs from th e final ar gument typ e on the o riginal ta rget, | |
933 | * the original target is adapted to take the array type directly, | |
934 | * as if by a ca ll to {@li nk #asType asType}. | |
935 | * <p> | |
936 | * Whe n called, the adapte r replaces its trail ing {@code arrayLeng th} | |
937 | * arg uments by a single n ew array o f type {@c ode arrayT ype}, whos e elements | |
938 | * com prise (in order) the replaced arguments. | |
939 | * Fin ally the t arget is c alled. | |
940 | * Wha t the targ et eventua lly return s is retur ned unchan ged by the adapter. | |
941 | * <p> | |
942 | * (Th e array ma y also be a shared c onstant wh en {@code arrayLengt h} is zero .) | |
943 | * <p> | |
944 | * (<e m>Note:</e m> The {@c ode arrayT ype} is of ten identi cal to the last | |
945 | * par ameter typ e of the o riginal ta rget. | |
946 | * It is an expl icit argum ent for sy mmetry wit h {@code a sSpreader} , and also | |
947 | * to allow the target to use a simp le {@code Object} as its last parameter type.) | |
948 | * <p> | |
949 | * In order to c reate a co llecting a dapter whi ch is not restricted to a part icular | |
950 | * num ber of col lected arg uments, us e {@link # asVarargsC ollector a sVarargsCo llector} i nstead. | |
951 | * <p> | |
952 | * Her e are some examples of array-c ollecting method han dles: | |
953 | * <bl ockquote>< pre>{@code | |
954 | MethodHand le deepToS tring = pu blicLookup () | |
955 | .findSta tic(Arrays .class, "d eepToStrin g", method Type(Strin g.class, O bject[].cl ass)); | |
956 | assertEqua ls("[won]" , (Strin g) deepToS tring.invo keExact(ne w Object[] {"won"})); | |
957 | MethodHand le ts1 = d eepToStrin g.asCollec tor(Object [].class, 1); | |
958 | assertEqua ls(methodT ype(String .class, Ob ject.class ), ts1.typ e()); | |
959 | //assertEq uals("[won ]", (Strin g) ts1.inv okeExact( ne w Object[] {"won"})); //FAIL | |
960 | assertEqua ls("[[won] ]", (Strin g) ts1.inv okeExact(( Object) ne w Object[] {"won"})); | |
961 | // arrayTy pe can be a subtype of Object[ ] | |
962 | MethodHand le ts2 = d eepToStrin g.asCollec tor(String [].class, 2); | |
963 | assertEqua ls(methodT ype(String .class, St ring.class , String.c lass), ts2 .type()); | |
964 | assertEqua ls("[two, too]", (St ring) ts2. invokeExac t("two", " too")); | |
965 | MethodHand le ts0 = d eepToStrin g.asCollec tor(Object [].class, 0); | |
966 | assertEqua ls("[]", ( String) ts 0.invokeEx act()); | |
967 | // collect ors can be nested, L isp-style | |
968 | MethodHand le ts22 = deepToStri ng.asColle ctor(Objec t[].class, 3).asColl ector(Stri ng[].class , 2); | |
969 | assertEqua ls("[A, B, [C, D]]", ((String) ts22.invo keExact((O bject)'A', (Object)" B", "C", " D"))); | |
970 | // arrayTy pe can be any primit ive array type | |
971 | MethodHand le bytesTo String = p ublicLooku p() | |
972 | .findSta tic(Arrays .class, "t oString", methodType (String.cl ass, byte[ ].class)) | |
973 | .asColle ctor(byte[ ].class, 3 ); | |
974 | assertEqua ls("[1, 2, 3]", (Str ing) bytes ToString.i nvokeExact ((byte)1, (byte)2, ( byte)3)); | |
975 | MethodHand le longsTo String = p ublicLooku p() | |
976 | .findSta tic(Arrays .class, "t oString", methodType (String.cl ass, long[ ].class)) | |
977 | .asColle ctor(long[ ].class, 1 ); | |
978 | assertEqua ls("[123]" , (String) longsToSt ring.invok eExact((lo ng)123)); | |
979 | * }</ pre></bloc kquote> | |
980 | * @pa ram arrayT ype often {@code Obj ect[]}, th e type of the array argument w hich will collect th e argument s | |
981 | * @pa ram arrayL ength the number of arguments to collect into a ne w array ar gument | |
982 | * @re turn a new method ha ndle which collects some trail ing argume nt | |
983 | * into an array, before cal ling the o riginal me thod handl e | |
984 | * @th rows NullP ointerExce ption if { @code arra yType} is a null ref erence | |
985 | * @th rows Illeg alArgument Exception if {@code arrayType} is not an array typ e | |
986 | * or {@ code array Type} is n ot assigna ble to thi s method h andle's tr ailing par ameter typ e, | |
987 | * or {@ code array Length} is not a leg al array s ize, | |
988 | * or th e resultin g method h andle's ty pe would h ave | |
989 | * <a hr ef="Method Handle.htm l#maxarity ">too many parameter s</a> | |
990 | * @th rows Wrong MethodType Exception if the imp lied {@cod e asType} call fails | |
991 | * @se e #asSprea der | |
992 | * @se e #asVarar gsCollecto r | |
993 | */ | |
994 | public MethodHan dle asColl ector(Clas s<?> array Type, int arrayLengt h) { | |
995 | as CollectorC hecks(arra yType, arr ayLength); | |
996 | in t collectA rgPos = ty pe().param eterCount( ) - 1; | |
997 | Bo undMethodH andle mh = rebind(); | |
998 | Me thodType r esultType = type().a sCollector Type(array Type, arra yLength); | |
999 | Me thodHandle newArray = MethodHa ndleImpl.v arargsArra y(arrayTyp e, arrayLe ngth); | |
1000 | La mbdaForm l form = mh. editor().c ollectArgu mentArrayF orm(1 + co llectArgPo s, newArra y); | |
1001 | if (lform != null) { | |
1002 | return m h.copyWith (resultTyp e, lform); | |
1003 | } | |
1004 | lf orm = mh.e ditor().co llectArgum entsForm(1 + collect ArgPos, ne wArray.typ e().basicT ype()); | |
1005 | re turn mh.co pyWithExte ndL(result Type, lfor m, newArra y); | |
1006 | } | |
1007 | ||
1008 | /** | |
1009 | * See if {@code asCollect or} can be validly c alled with the given arguments . | |
1010 | * Ret urn false if the las t paramete r is not a n exact ma tch to arr ayType. | |
1011 | */ | |
1012 | /*non- public*/ b oolean asC ollectorCh ecks(Class <?> arrayT ype, int a rrayLength ) { | |
1013 | sp readArrayC hecks(arra yType, arr ayLength); | |
1014 | in t nargs = type().par ameterCoun t(); | |
1015 | if (nargs != 0) { | |
1016 | Class<?> lastParam = type(). parameterT ype(nargs- 1); | |
1017 | if (last Param == a rrayType) return tr ue; | |
1018 | if (last Param.isAs signableFr om(arrayTy pe)) retu rn false; | |
1019 | } | |
1020 | th row newIll egalArgume ntExceptio n("array t ype not as signable t o trailing argument" , this, ar rayType); | |
1021 | } | |
1022 | ||
1023 | /** | |
1024 | * Mak es a <em>v ariable ar ity</em> a dapter whi ch is able to accept | |
1025 | * any number of trailing positional arguments and colle ct them | |
1026 | * int o an array argument. | |
1027 | * <p> | |
1028 | * The type and behavior o f the adap ter will b e the same as | |
1029 | * the type and behavior o f the targ et, except that cert ain | |
1030 | * {@c ode invoke } and {@co de asType} requests can lead t o | |
1031 | * tra iling posi tional arg uments bei ng collect ed into ta rget's | |
1032 | * tra iling para meter. | |
1033 | * Als o, the las t paramete r type of the adapte r will be | |
1034 | * {@c ode arrayT ype}, even if the ta rget has a different | |
1035 | * las t paramete r type. | |
1036 | * <p> | |
1037 | * Thi s transfor mation may return {@ code this} if the me thod handl e is | |
1038 | * alr eady of va riable ari ty and its trailing parameter type | |
1039 | * is identical to {@code arrayType} . | |
1040 | * <p> | |
1041 | * Whe n called w ith {@link #invokeEx act invoke Exact}, th e adapter invokes | |
1042 | * the target wi th no argu ment chang es. | |
1043 | * (<e m>Note:</e m> This be havior is different from a | |
1044 | * {@l inkplain # asCollecto r fixed ar ity collec tor}, | |
1045 | * sin ce it acce pts a whol e array of indetermi nate lengt h, | |
1046 | * rat her than a fixed num ber of arg uments.) | |
1047 | * <p> | |
1048 | * Whe n called w ith plain, inexact { @link #inv oke invoke }, if the caller | |
1049 | * typ e is the s ame as the adapter, the adapte r invokes the target as with | |
1050 | * {@c ode invoke Exact}. | |
1051 | * (Th is is the normal beh avior for {@code inv oke} when types matc h.) | |
1052 | * <p> | |
1053 | * Oth erwise, if the calle r and adap ter arity are the sa me, and th e | |
1054 | * tra iling para meter type of the ca ller is a reference type ident ical to | |
1055 | * or assignable to the tr ailing par ameter typ e of the a dapter, | |
1056 | * the arguments and retur n values a re convert ed pairwis e, | |
1057 | * as if by {@li nk #asType asType} o n a fixed arity | |
1058 | * met hod handle . | |
1059 | * <p> | |
1060 | * Oth erwise, th e arities differ, or the adapt er's trail ing parame ter | |
1061 | * typ e is not a ssignable from the c orrespondi ng caller type. | |
1062 | * In this case, the adapt er replace s all trai ling argum ents from | |
1063 | * the original trailing a rgument po sition onw ard, by | |
1064 | * a n ew array o f type {@c ode arrayT ype}, whos e elements | |
1065 | * com prise (in order) the replaced arguments. | |
1066 | * <p> | |
1067 | * The caller ty pe must pr ovides as least enou gh argumen ts, | |
1068 | * and of the co rrect type , to satis fy the tar get's requ irement fo r | |
1069 | * pos itional ar guments be fore the t railing ar ray argume nt. | |
1070 | * Thu s, the cal ler must s upply, at a minimum, {@code N- 1} argumen ts, | |
1071 | * whe re {@code N} is the arity of t he target. | |
1072 | * Als o, there m ust exist conversion s from the incoming arguments | |
1073 | * to the target 's argumen ts. | |
1074 | * As with other uses of p lain {@cod e invoke}, if these basic | |
1075 | * req uirements are not fu lfilled, a {@code Wr ongMethodT ypeExcepti on} | |
1076 | * may be thrown . | |
1077 | * <p> | |
1078 | * In all cases, what the target eve ntually re turns is r eturned un changed by the adapt er. | |
1079 | * <p> | |
1080 | * In the final case, it i s exactly as if the target met hod handle were | |
1081 | * tem porarily a dapted wit h a {@link plain #asC ollector f ixed arity collector } | |
1082 | * to the arity required b y the call er type. | |
1083 | * (As with {@co de asColle ctor}, if the array length is zero, | |
1084 | * a s hared cons tant may b e used ins tead of a new array. | |
1085 | * If the implie d call to {@code asC ollector} would thro w | |
1086 | * an {@code Ill egalArgume ntExceptio n} or {@co de WrongMe thodTypeEx ception}, | |
1087 | * the call to t he variabl e arity ad apter must throw | |
1088 | * {@c ode WrongM ethodTypeE xception}. ) | |
1089 | * <p> | |
1090 | * The behavior of {@link #asType as Type} is a lso specia lized for | |
1091 | * var iable arit y adapters , to maint ain the in variant th at | |
1092 | * pla in, inexac t {@code i nvoke} is always equ ivalent to an {@code asType} | |
1093 | * cal l to adjus t the targ et type, f ollowed by {@code in vokeExact} . | |
1094 | * The refore, a variable a rity adapt er respond s | |
1095 | * to an {@code asType} re quest by b uilding a fixed arit y collecto r, | |
1096 | * if and only i f the adap ter and re quested ty pe differ either | |
1097 | * in arity or t railing ar gument typ e. | |
1098 | * The resulting fixed ari ty collect or has its type furt her adjust ed | |
1099 | * (if necessary ) to the r equested t ype by pai rwise conv ersion, | |
1100 | * as if by anot her applic ation of { @code asTy pe}. | |
1101 | * <p> | |
1102 | * Whe n a method handle is obtained by executi ng an {@co de ldc} in struction | |
1103 | * of a {@code C ONSTANT_Me thodHandle } constant , and the target met hod is mar ked | |
1104 | * as a variable arity met hod (with the modifi er bit {@c ode 0x0080 }), | |
1105 | * the method ha ndle will accept mul tiple arit ies, as if the metho d handle | |
1106 | * con stant were created b y means of a call to {@code as VarargsCol lector}. | |
1107 | * <p> | |
1108 | * In order to c reate a co llecting a dapter whi ch collect s a predet ermined | |
1109 | * num ber of arg uments, an d whose ty pe reflect s this pre determined number, | |
1110 | * use {@link #a sCollector asCollect or} instea d. | |
1111 | * <p> | |
1112 | * No method han dle transf ormations produce ne w method h andles wit h | |
1113 | * var iable arit y, unless they are d ocumented as doing s o. | |
1114 | * The refore, be sides {@co de asVarar gsCollecto r}, | |
1115 | * all methods i n {@code M ethodHandl e} and {@c ode Method Handles} | |
1116 | * wil l return a method ha ndle with fixed arit y, | |
1117 | * exc ept in the cases whe re they ar e specifie d to retur n their or iginal | |
1118 | * ope rand (e.g. , {@code a sType} of the method handle's own type). | |
1119 | * <p> | |
1120 | * Cal ling {@cod e asVararg sCollector } on a met hod handle which is already | |
1121 | * of variable a rity will produce a method han dle with t he same ty pe and beh avior. | |
1122 | * It may (or ma y not) ret urn the or iginal var iable arit y method h andle. | |
1123 | * <p> | |
1124 | * Her e is an ex ample, of a list-mak ing variab le arity m ethod hand le: | |
1125 | * <bl ockquote>< pre>{@code | |
1126 | MethodHand le deepToS tring = pu blicLookup () | |
1127 | .findSta tic(Arrays .class, "d eepToStrin g", method Type(Strin g.class, O bject[].cl ass)); | |
1128 | MethodHand le ts1 = d eepToStrin g.asVararg sCollector (Object[]. class); | |
1129 | assertEqua ls("[won]" , (Strin g) ts1.inv okeExact( new Obj ect[]{"won "})); | |
1130 | assertEqua ls("[won]" , (Strin g) ts1.inv oke( new Obj ect[]{"won "})); | |
1131 | assertEqua ls("[won]" , (Strin g) ts1.inv oke( "won " )); | |
1132 | assertEqua ls("[[won] ]", (Strin g) ts1.inv oke((Objec t) new Obj ect[]{"won "})); | |
1133 | // findSta tic of Arr ays.asList (...) prod uces a var iable arit y method h andle: | |
1134 | MethodHand le asList = publicLo okup() | |
1135 | .findSta tic(Arrays .class, "a sList", me thodType(L ist.class, Object[]. class)); | |
1136 | assertEqua ls(methodT ype(List.c lass, Obje ct[].class ), asList. type()); | |
1137 | assert(asL ist.isVara rgsCollect or()); | |
1138 | assertEqua ls("[]", a sList.invo ke().toStr ing()); | |
1139 | assertEqua ls("[1]", asList.inv oke(1).toS tring()); | |
1140 | assertEqua ls("[two, too]", asL ist.invoke ("two", "t oo").toStr ing()); | |
1141 | String[] a rgv = { "t hree", "th ee", "tee" }; | |
1142 | assertEqua ls("[three , thee, te e]", asLis t.invoke(a rgv).toStr ing()); | |
1143 | assertEqua ls("[three , thee, te e]", asLis t.invoke(( Object[])a rgv).toStr ing()); | |
1144 | List ls = (List) asL ist.invoke ((Object)a rgv); | |
1145 | assertEqua ls(1, ls.s ize()); | |
1146 | assertEqua ls("[three , thee, te e]", Array s.toString ((Object[] )ls.get(0) )); | |
1147 | * }</ pre></bloc kquote> | |
1148 | * <p style="fon t-size:sma ller;"> | |
1149 | * <em >Discussio n:</em> | |
1150 | * The se rules a re designe d as a dyn amically-t yped varia tion | |
1151 | * of the Java r ules for v ariable ar ity method s. | |
1152 | * In both cases , callers to a varia ble arity method or method han dle | |
1153 | * can either pa ss zero or more posi tional arg uments, or else pass | |
1154 | * pre -collected arrays of any lengt h. Users should be aware of t he | |
1155 | * spe cial role of the fin al argumen t, and of the effect of a | |
1156 | * typ e match on that fina l argument , which de termines w hether | |
1157 | * or not a sing le trailin g argument is interp reted as a whole | |
1158 | * arr ay or a si ngle eleme nt of an a rray to be collected . | |
1159 | * Not e that the dynamic t ype of the trailing argument h as no | |
1160 | * eff ect on thi s decision , only a c omparison between th e symbolic | |
1161 | * typ e descript or of the call site and the ty pe descrip tor of the method ha ndle.) | |
1162 | * | |
1163 | * @pa ram arrayT ype often {@code Obj ect[]}, th e type of the array argument w hich will collect th e argument s | |
1164 | * @re turn a new method ha ndle which can colle ct any num ber of tra iling argu ments | |
1165 | * into an array, before cal ling the o riginal me thod handl e | |
1166 | * @th rows NullP ointerExce ption if { @code arra yType} is a null ref erence | |
1167 | * @th rows Illeg alArgument Exception if {@code arrayType} is not an array typ e | |
1168 | * or {@ code array Type} is n ot assigna ble to thi s method h andle's tr ailing par ameter typ e | |
1169 | * @se e #asColle ctor | |
1170 | * @se e #isVarar gsCollecto r | |
1171 | * @se e #asFixed Arity | |
1172 | */ | |
1173 | public MethodHan dle asVara rgsCollect or(Class<? > arrayTyp e) { | |
1174 | ar rayType.ge tClass(); // explici t NPE | |
1175 | bo olean last Match = as CollectorC hecks(arra yType, 0); | |
1176 | if (isVararg sCollector () && last Match) | |
1177 | return t his; | |
1178 | re turn Metho dHandleImp l.makeVara rgsCollect or(this, a rrayType); | |
1179 | } | |
1180 | ||
1181 | /** | |
1182 | * Det ermines if this meth od handle | |
1183 | * sup ports {@li nkplain #a sVarargsCo llector va riable ari ty} calls. | |
1184 | * Suc h method h andles ari se from th e followin g sources: | |
1185 | * <ul > | |
1186 | * <li >a call to {@linkpla in #asVara rgsCollect or asVarar gsCollecto r} | |
1187 | * <li >a call to a {@linkp lain java. lang.invok e.MethodHa ndles.Look up lookup method} | |
1188 | * which res olves to a variable arity Java method or construct or | |
1189 | * <li >an {@code ldc} inst ruction of a {@code CONSTANT_M ethodHandl e} | |
1190 | * which res olves to a variable arity Java method or construct or | |
1191 | * </u l> | |
1192 | * @re turn true if this me thod handl e accepts more than one arity of plain, inexact {@ code invok e} calls | |
1193 | * @se e #asVarar gsCollecto r | |
1194 | * @se e #asFixed Arity | |
1195 | */ | |
1196 | public boolean i sVarargsCo llector() { | |
1197 | re turn false ; | |
1198 | } | |
1199 | ||
1200 | /** | |
1201 | * Mak es a <em>f ixed arity </em> meth od handle which is o therwise | |
1202 | * equ ivalent to the curre nt method handle. | |
1203 | * <p> | |
1204 | * If the curren t method h andle is n ot of | |
1205 | * {@l inkplain # asVarargsC ollector v ariable ar ity}, | |
1206 | * the current m ethod hand le is retu rned. | |
1207 | * Thi s is true even if th e current method han dle | |
1208 | * cou ld not be a valid in put to {@c ode asVara rgsCollect or}. | |
1209 | * <p> | |
1210 | * Oth erwise, th e resultin g fixed-ar ity method handle ha s the same | |
1211 | * typ e and beha vior of th e current method han dle, | |
1212 | * exc ept that { @link #isV arargsColl ector isVa rargsColle ctor} | |
1213 | * wil l be false . | |
1214 | * The fixed-ari ty method handle may (or may n ot) be the | |
1215 | * a p revious ar gument to {@code asV arargsColl ector}. | |
1216 | * <p> | |
1217 | * Her e is an ex ample, of a list-mak ing variab le arity m ethod hand le: | |
1218 | * <bl ockquote>< pre>{@code | |
1219 | MethodHand le asListV ar = publi cLookup() | |
1220 | .findSta tic(Arrays .class, "a sList", me thodType(L ist.class, Object[]. class)) | |
1221 | .asVarar gsCollecto r(Object[] .class); | |
1222 | MethodHand le asListF ix = asLis tVar.asFix edArity(); | |
1223 | assertEqua ls("[1]", asListVar. invoke(1). toString() ); | |
1224 | Exception caught = n ull; | |
1225 | try { asLi stFix.invo ke((Object )1); } | |
1226 | catch (Exc eption ex) { caught = ex; } | |
1227 | assert(cau ght instan ceof Class CastExcept ion); | |
1228 | assertEqua ls("[two, too]", asL istVar.inv oke("two", "too").to String()); | |
1229 | try { asLi stFix.invo ke("two", "too"); } | |
1230 | catch (Exc eption ex) { caught = ex; } | |
1231 | assert(cau ght instan ceof Wrong MethodType Exception) ; | |
1232 | Object[] a rgv = { "t hree", "th ee", "tee" }; | |
1233 | assertEqua ls("[three , thee, te e]", asLis tVar.invok e(argv).to String()); | |
1234 | assertEqua ls("[three , thee, te e]", asLis tFix.invok e(argv).to String()); | |
1235 | assertEqua ls(1, ((Li st) asList Var.invoke ((Object)a rgv)).size ()); | |
1236 | assertEqua ls("[three , thee, te e]", asLis tFix.invok e((Object) argv).toSt ring()); | |
1237 | * }</ pre></bloc kquote> | |
1238 | * | |
1239 | * @re turn a new method ha ndle which accepts o nly a fixe d number o f argument s | |
1240 | * @se e #asVarar gsCollecto r | |
1241 | * @se e #isVarar gsCollecto r | |
1242 | */ | |
1243 | public MethodHan dle asFixe dArity() { | |
1244 | as sert(!isVa rargsColle ctor()); | |
1245 | re turn this; | |
1246 | } | |
1247 | ||
1248 | /** | |
1249 | * Bin ds a value {@code x} to the fi rst argume nt of a me thod handl e, without invoking it. | |
1250 | * The new metho d handle a dapts, as its <i>tar get</i>, | |
1251 | * the current m ethod hand le by bind ing it to the given argument. | |
1252 | * The type of t he bound h andle will be | |
1253 | * the same as t he type of the targe t, except that a sin gle leadin g | |
1254 | * ref erence par ameter wil l be omitt ed. | |
1255 | * <p> | |
1256 | * Whe n called, the bound handle ins erts the g iven value {@code x} | |
1257 | * as a new lead ing argume nt to the target. T he other a rguments a re | |
1258 | * als o passed u nchanged. | |
1259 | * Wha t the targ et eventua lly return s is retur ned unchan ged by the bound han dle. | |
1260 | * <p> | |
1261 | * The reference {@code x} must be c onvertible to the fi rst parame ter | |
1262 | * typ e of the t arget. | |
1263 | * <p> | |
1264 | * (<e m>Note:</e m> Becaus e method h andles are immutable , the targ et method handle | |
1265 | * ret ains its o riginal ty pe and beh avior.) | |
1266 | * @pa ram x the value to bind to th e first ar gument of the target | |
1267 | * @re turn a new method ha ndle which prepends the given value to t he incomin g | |
1268 | * argum ent list, before cal ling the o riginal me thod handl e | |
1269 | * @th rows Illeg alArgument Exception if the tar get does n ot have a | |
1270 | * leadi ng paramet er type th at is a re ference ty pe | |
1271 | * @th rows Class CastExcept ion if {@c ode x} can not be con verted | |
1272 | * to th e leading parameter type of th e target | |
1273 | * @se e MethodHa ndles#inse rtArgument s | |
1274 | */ | |
1275 | public MethodHan dle bindTo (Object x) { | |
1276 | x = type.lea dingRefere nceParamet er().cast( x); // th row CCE if needed | |
1277 | re turn bindA rgumentL(0 , x); | |
1278 | } | |
1279 | ||
1280 | /** | |
1281 | * Ret urns a str ing repres entation o f the meth od handle, | |
1282 | * sta rting with the strin g {@code " MethodHand le"} and | |
1283 | * end ing with t he string representa tion of th e method h andle's ty pe. | |
1284 | * In other word s, this me thod retur ns a strin g equal to the value of: | |
1285 | * <bl ockquote>< pre>{@code | |
1286 | * "Me thodHandle " + type() .toString( ) | |
1287 | * }</ pre></bloc kquote> | |
1288 | * <p> | |
1289 | * (<e m>Note:</e m> Future releases of this AP I may add further in formation | |
1290 | * to the string represent ation. | |
1291 | * The refore, th e present syntax sho uld not be parsed by applicati ons.) | |
1292 | * | |
1293 | * @re turn a str ing repres entation o f the meth od handle | |
1294 | */ | |
1295 | @Overr ide | |
1296 | public String to String() { | |
1297 | if (DEBUG_ME THOD_HANDL E_NAMES) return "Me thodHandle "+debugStr ing(); | |
1298 | re turn stand ardString( ); | |
1299 | } | |
1300 | String standardS tring() { | |
1301 | re turn "Meth odHandle"+ type; | |
1302 | } | |
1303 | /** Re turn a str ing with a several l ines descr ibing the method han dle struct ure. | |
1304 | * Th is string would be s uitable fo r display in an IDE debugger. | |
1305 | */ | |
1306 | String debugStri ng() { | |
1307 | re turn type+ " : "+inte rnalForm() +internalP roperties( ); | |
1308 | } | |
1309 | ||
1310 | //// I mplementat ion method s. | |
1311 | //// S ub-classes can overr ide these default im plementati ons. | |
1312 | //// A ll these m ethods ass ume argume nts are al ready vali dated. | |
1313 | ||
1314 | // Oth er transfo rms to do: convert, explicitC ast, permu te, drop, filter, fo ld, GWT, c atch | |
1315 | ||
1316 | BoundM ethodHandl e bindArgu mentL(int pos, Objec t value) { | |
1317 | re turn rebin d().bindAr gumentL(po s, value); | |
1318 | } | |
1319 | ||
1320 | /*non- public*/ | |
1321 | Method Handle set Varargs(Me mberName m ember) thr ows Illega lAccessExc eption { | |
1322 | if (!member. isVarargs( )) return this; | |
1323 | Cl ass<?> arr ayType = t ype().last ParameterT ype(); | |
1324 | if (arrayTyp e.isArray( )) { | |
1325 | return M ethodHandl eImpl.make VarargsCol lector(thi s, arrayTy pe); | |
1326 | } | |
1327 | th row member .makeAcces sException ("cannot m ake variab le arity", null); | |
1328 | } | |
1329 | ||
1330 | /*non- public*/ | |
1331 | Method Handle vie wAsType(Me thodType n ewType, bo olean stri ct) { | |
1332 | // No actual conversio ns, just a new view of the sam e method. | |
1333 | // Note that this oper ation must not produ ce a Direc tMethodHan dle, | |
1334 | // because r etyped DMH s, like an y transfor med MHs, | |
1335 | // cannot be cracked i nto Method HandleInfo . | |
1336 | as sert viewA sTypeCheck s(newType, strict); | |
1337 | Bo undMethodH andle mh = rebind(); | |
1338 | as sert(!((Me thodHandle )mh instan ceof Direc tMethodHan dle)); | |
1339 | re turn mh.co pyWith(new Type, mh.f orm); | |
1340 | } | |
1341 | ||
1342 | /*non- public*/ | |
1343 | boolea n viewAsTy peChecks(M ethodType newType, b oolean str ict) { | |
1344 | if (strict) { | |
1345 | assert(t ype().isVi ewableAs(n ewType, tr ue)) | |
1346 | : Ar rays.asLis t(this, ne wType); | |
1347 | } else { | |
1348 | assert(t ype().basi cType().is ViewableAs (newType.b asicType() , true)) | |
1349 | : Ar rays.asLis t(this, ne wType); | |
1350 | } | |
1351 | re turn true; | |
1352 | } | |
1353 | ||
1354 | // Dec oding | |
1355 | ||
1356 | /*non- public*/ | |
1357 | Lambda Form inter nalForm() { | |
1358 | re turn form; | |
1359 | } | |
1360 | ||
1361 | /*non- public*/ | |
1362 | Member Name inter nalMemberN ame() { | |
1363 | re turn null; // DMH r eturns DMH .member | |
1364 | } | |
1365 | ||
1366 | /*non- public*/ | |
1367 | Class< ?> interna lCallerCla ss() { | |
1368 | re turn null; // calle r-bound MH for @Call erSensitiv e method r eturns cal ler | |
1369 | } | |
1370 | ||
1371 | /*non- public*/ | |
1372 | Method HandleImpl .Intrinsic intrinsic Name() { | |
1373 | // no specia l intrinsi c meaning to most MH s | |
1374 | re turn Metho dHandleImp l.Intrinsi c.NONE; | |
1375 | } | |
1376 | ||
1377 | /*non- public*/ | |
1378 | Method Handle wit hInternalM emberName( MemberName member, b oolean isI nvokeSpeci al) { | |
1379 | if (member ! = null) { | |
1380 | return M ethodHandl eImpl.make WrappedMem ber(this, member, is InvokeSpec ial); | |
1381 | } else if (i nternalMem berName() == null) { | |
1382 | // The r equired in ternaMembe rName is n ull, and t his MH (li ke most) d oesn't hav e one. | |
1383 | return t his; | |
1384 | } else { | |
1385 | // The f ollowing c ase is rar e. Mask th e internal MemberName by wrappi ng the MH in a BMH. | |
1386 | MethodHa ndle resul t = rebind (); | |
1387 | assert ( result.int ernalMembe rName() == null); | |
1388 | return r esult; | |
1389 | } | |
1390 | } | |
1391 | ||
1392 | /*non- public*/ | |
1393 | boolea n isInvoke Special() { | |
1394 | re turn false ; // DMH. Special re turns true | |
1395 | } | |
1396 | ||
1397 | /*non- public*/ | |
1398 | Object internalV alues() { | |
1399 | re turn null; | |
1400 | } | |
1401 | ||
1402 | /*non- public*/ | |
1403 | Object internalP roperties( ) { | |
1404 | // Override to somethi ng to foll ow this.fo rm, like " \n& FOO=ba r" | |
1405 | re turn ""; | |
1406 | } | |
1407 | ||
1408 | //// M ethod hand le impleme ntation me thods. | |
1409 | //// S ub-classes can overr ide these default im plementati ons. | |
1410 | //// A ll these m ethods ass ume argume nts are al ready vali dated. | |
1411 | ||
1412 | /*non- public*/ | |
1413 | abstra ct MethodH andle copy With(Metho dType mt, LambdaForm lf); | |
1414 | ||
1415 | /** Re quire this method ha ndle to be a BMH, or else repl ace it wit h a "wrapp er" BMH. | |
1416 | * Ma ny transfo rms are im plemented only for B MHs. | |
1417 | * @r eturn a be haviorally equivalen t BMH | |
1418 | */ | |
1419 | abstra ct BoundMe thodHandle rebind(); | |
1420 | ||
1421 | /** | |
1422 | * Rep lace the o ld lambda form of th is method handle wit h a new on e. | |
1423 | * The new one m ust be fun ctionally equivalent to the ol d one. | |
1424 | * Thr eads may c ontinue ru nning the old form i ndefinitel y, | |
1425 | * but it is lik ely that t he new one will be p referred f or new exe cutions. | |
1426 | * Use with disc retion. | |
1427 | */ | |
1428 | /*non- public*/ | |
1429 | void u pdateForm( LambdaForm newForm) { | |
1430 | as sert(newFo rm.customi zed == nul l || newFo rm.customi zed == thi s); | |
1431 | if (form == newForm) return; | |
1432 | ne wForm.prep are(); // as in Met hodHandle. <init> | |
1433 | UN SAFE.putOb ject(this, FORM_OFFS ET, newFor m); | |
1434 | UN SAFE.fullF ence(); | |
1435 | } | |
1436 | ||
1437 | /** Cr aft a Lamb daForm cus tomized fo r this par ticular Me thodHandle */ | |
1438 | /*non- public*/ | |
1439 | void c ustomize() { | |
1440 | if (form.cus tomized == null) { | |
1441 | LambdaFo rm newForm = form.cu stomize(th is); | |
1442 | updateFo rm(newForm ); | |
1443 | } else { | |
1444 | assert(f orm.custom ized == th is); | |
1445 | } | |
1446 | } | |
1447 | ||
1448 | privat e static f inal long FORM_OFFSE T; | |
1449 | static { | |
1450 | tr y { | |
1451 | FORM_OFF SET = UNSA FE.objectF ieldOffset (MethodHan dle.class. getDeclare dField("fo rm")); | |
1452 | } catch (Ref lectiveOpe rationExce ption ex) { | |
1453 | throw ne wInternalE rror(ex); | |
1454 | } | |
1455 | } | |
1456 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.