painless-types.asciidoc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. [[painless-types]]
  2. === Types
  3. A type is a classification of data used to define the properties of a value.
  4. These properties specify what data a value represents and the rules for how a
  5. value is evaluated during an <<painless-operators, operation>>. Each type
  6. belongs to one of the following categories: <<primitive-types, primitive>>,
  7. <<reference-types, reference>>, or <<dynamic-types, dynamic>>.
  8. [[primitive-types]]
  9. ==== Primitive Types
  10. A primitive type represents basic data built natively into the JVM and is
  11. allocated to non-heap memory. Declare a primitive type
  12. <<painless-variables, variable>> or access a primitive type member field (from
  13. a reference type instance), and assign it a primitive type value for evaluation
  14. during later operations. The default value for a newly-declared primitive type
  15. variable is listed as part of the definitions below. A primitive type value is
  16. copied during an assignment or as an argument for a method/function call.
  17. A primitive type has a corresponding reference type (also known as a boxed
  18. type). Use the <<field-access-operator, field access operator>> or
  19. <<method-call-operator, method call operator>> on a primitive type value to
  20. force evaluation as its corresponding reference type value.
  21. The following primitive types are available:
  22. [horizontal]
  23. `byte`::
  24. 8-bit, signed, two's complement integer
  25. * range: [`-128`, `127`]
  26. * default value: `0`
  27. * reference type: `Byte`
  28. `short`::
  29. 16-bit, signed, two's complement integer
  30. * range: [`-32768`, `32767`]
  31. * default value: `0`
  32. * reference type: `Short`
  33. `char`::
  34. 16-bit, unsigned, Unicode character
  35. * range: [`0`, `65535`]
  36. * default value: `0` or `\u0000`
  37. * reference type: `Character`
  38. `int`::
  39. 32-bit, signed, two's complement integer
  40. * range: [`-2^32`, `2^32-1`]
  41. * default value: `0`
  42. * reference type: `Integer`
  43. `long`::
  44. 64-bit, signed, two's complement integer
  45. * range: [`-2^64`, `2^64-1`]
  46. * default value: `0`
  47. * reference type: `Long`
  48. `float`::
  49. 32-bit, signed, single-precision, IEEE 754 floating point number
  50. * default value: `0.0`
  51. * reference type: `Float`
  52. `double`::
  53. 64-bit, signed, double-precision, IEEE 754 floating point number
  54. * default value: `0.0`
  55. * reference type: `Double`
  56. `boolean`::
  57. logical quantity with two possible values of `true` and `false`
  58. * default value: `false`
  59. * reference type: `Boolean`
  60. *Examples*
  61. * Primitive types used in declaration, declaration and assignment.
  62. +
  63. [source,Painless]
  64. ----
  65. <1> int i = 1;
  66. <2> double d;
  67. <3> boolean b = true;
  68. ----
  69. +
  70. <1> declare `int i`;
  71. store `int 1` to `i`
  72. <2> declare `double d`;
  73. store default `double 0.0` to `d`
  74. <3> declare `boolean b`;
  75. store `boolean true` to `b`
  76. +
  77. * Method call on a primitive type using the corresponding reference type.
  78. +
  79. [source,Painless]
  80. ----
  81. <1> int i = 1;
  82. <2> i.toString();
  83. ----
  84. +
  85. <1> declare `int i`;
  86. store `int 1` to `i`
  87. <2> load from `i` -> `int 1`;
  88. box `int 1` -> `Integer 1 reference`;
  89. call `toString` on `Integer 1 reference` -> `String '1'`
  90. [[reference-types]]
  91. ==== Reference Types
  92. A reference type is a named construct (object), potentially representing
  93. multiple pieces of data (member fields) and logic to manipulate that data
  94. (member methods), defined as part of the application programming interface
  95. (API) for scripts.
  96. A reference type instance is a single set of data for one reference type
  97. object allocated to the heap. Use the
  98. <<new-instance-operator, new instance operator>> to allocate a reference type
  99. instance. Use a reference type instance to load from, store to, and manipulate
  100. complex data.
  101. A reference type value refers to a reference type instance, and multiple
  102. reference type values may refer to the same reference type instance. A change to
  103. a reference type instance will affect all reference type values referring to
  104. that specific instance.
  105. Declare a reference type <<painless-variables, variable>> or access a reference
  106. type member field (from a reference type instance), and assign it a reference
  107. type value for evaluation during later operations. The default value for a
  108. newly-declared reference type variable is `null`. A reference type value is
  109. shallow-copied during an assignment or as an argument for a method/function
  110. call. Assign `null` to a reference type variable to indicate the reference type
  111. value refers to no reference type instance. The JVM will garbage collect a
  112. reference type instance when it is no longer referred to by any reference type
  113. values. Pass `null` as an argument to a method/function call to indicate the
  114. argument refers to no reference type instance.
  115. A reference type object defines zero-to-many of each of the following:
  116. static member field::
  117. A static member field is a named and typed piece of data. Each reference type
  118. *object* contains one set of data representative of its static member fields.
  119. Use the <<field-access-operator, field access operator>> in correspondence with
  120. the reference type object name to access a static member field for loading and
  121. storing to a specific reference type *object*. No reference type instance
  122. allocation is necessary to use a static member field.
  123. non-static member field::
  124. A non-static member field is a named and typed piece of data. Each reference
  125. type *instance* contains one set of data representative of its reference type
  126. object's non-static member fields. Use the
  127. <<field-access-operator, field access operator>> for loading and storing to a
  128. non-static member field of a specific reference type *instance*. An allocated
  129. reference type instance is required to use a non-static member field.
  130. static member method::
  131. A static member method is a <<painless-functions, function>> called on a
  132. reference type *object*. Use the <<method-call-operator, method call operator>>
  133. in correspondence with the reference type object name to call a static member
  134. method. No reference type instance allocation is necessary to use a static
  135. member method.
  136. non-static member method::
  137. A non-static member method is a <<painless-functions, function>> called on a
  138. reference type *instance*. A non-static member method called on a reference type
  139. instance can load from and store to non-static member fields of that specific
  140. reference type instance. Use the <<method-call-operator, method call operator>>
  141. in correspondence with a specific reference type instance to call a non-static
  142. member method. An allocated reference type instance is required to use a
  143. non-static member method.
  144. constructor::
  145. A constructor is a special type of <<painless-functions, function>> used to
  146. allocate a reference type *instance* defined by a specific reference type
  147. *object*. Use the <<new-instance-operator, new instance operator>> to allocate
  148. a reference type instance.
  149. A reference type object follows a basic inheritance model. Consider types A and
  150. B. Type A is considered to be a parent of B, and B a child of A, if B inherits
  151. (is able to access as its own) all of A's non-static members. Type B is
  152. considered a descendant of A if there exists a recursive parent-child
  153. relationship from B to A with none to many types in between. In this case, B
  154. inherits all of A's non-static members along with all of the non-static members
  155. of the types in between. Type B is also considered to be a type A in both
  156. relationships.
  157. *Examples*
  158. * Reference types evaluated in several different operations.
  159. +
  160. [source,Painless]
  161. ----
  162. <1> List l = new ArrayList();
  163. <2> l.add(1);
  164. <3> int i = l.get(0) + 2;
  165. ----
  166. +
  167. <1> declare `List l`;
  168. allocate `ArrayList` instance -> `ArrayList reference`;
  169. implicit cast `ArrayList reference` to `List reference` -> `List reference`;
  170. store `List reference` to `l`
  171. <2> load from `l` -> `List reference`;
  172. implicit cast `int 1` to `def` -> `def`
  173. call `add` on `List reference` with arguments (`def`)
  174. <3> declare `int i`;
  175. load from `l` -> `List reference`;
  176. call `get` on `List reference` with arguments (`int 0`) -> `def`;
  177. implicit cast `def` to `int 1` -> `int 1`;
  178. add `int 1` and `int 2` -> `int 3`;
  179. store `int 3` to `i`
  180. +
  181. * Sharing a reference type instance.
  182. +
  183. [source,Painless]
  184. ----
  185. <1> List l0 = new ArrayList();
  186. <2> List l1 = l0;
  187. <3> l0.add(1);
  188. <4> l1.add(2);
  189. <5> int i = l1.get(0) + l0.get(1);
  190. ----
  191. +
  192. <1> declare `List l0`;
  193. allocate `ArrayList` instance -> `ArrayList reference`;
  194. implicit cast `ArrayList reference` to `List reference` -> `List reference`;
  195. store `List reference` to `l0`
  196. <2> declare `List l1`;
  197. load from `l0` -> `List reference`;
  198. store `List reference` to `l1`
  199. (note `l0` and `l1` refer to the same instance known as a shallow-copy)
  200. <3> load from `l0` -> `List reference`;
  201. implicit cast `int 1` to `def` -> `def`
  202. call `add` on `List reference` with arguments (`def`)
  203. <4> load from `l1` -> `List reference`;
  204. implicit cast `int 2` to `def` -> `def`
  205. call `add` on `List reference` with arguments (`def`)
  206. <5> declare `int i`;
  207. load from `l0` -> `List reference`;
  208. call `get` on `List reference` with arguments (`int 0`) -> `def @0`;
  209. implicit cast `def @0` to `int 1` -> `int 1`;
  210. load from `l1` -> `List reference`;
  211. call `get` on `List reference` with arguments (`int 1`) -> `def @1`;
  212. implicit cast `def @1` to `int 2` -> `int 2`;
  213. add `int 1` and `int 2` -> `int 3`;
  214. store `int 3` to `i`;
  215. +
  216. * Using the static members of a reference type.
  217. +
  218. [source,Painless]
  219. ----
  220. <1> int i = Integer.MAX_VALUE;
  221. <2> long l = Long.parseLong("123L");
  222. ----
  223. +
  224. <1> declare `int i`;
  225. load from `MAX_VALUE` on `Integer` -> `int 2147483647`;
  226. store `int 2147483647` to `i`
  227. <2> declare `long l`;
  228. call `parseLong` on `Long` with arguments (`long 123`) -> `long 123`;
  229. store `long 123` to `l`
  230. [[dynamic-types]]
  231. ==== Dynamic Types
  232. A dynamic type value can represent the value of any primitive type or
  233. reference type using a single type name `def`. A `def` type value mimics
  234. the behavior of whatever value it represents at run-time and will always
  235. represent the child-most descendant type value of any type value when evaluated
  236. during operations.
  237. Declare a `def` type <<painless-variables, variable>> or access a `def` type
  238. member field (from a reference type instance), and assign it any type of value
  239. for evaluation during later operations. The default value for a newly-declared
  240. `def` type variable is `null`. A `def` type variable or method/function
  241. parameter can change the type it represents during the compilation and
  242. evaluation of a script.
  243. Using the `def` type can have a slight impact on performance. Use only primitive
  244. types and reference types directly when performance is critical.
  245. *Errors*
  246. * If a `def` type value represents an inappropriate type for evaluation of an
  247. operation at run-time.
  248. *Examples*
  249. * General uses of the `def` type.
  250. +
  251. [source,Painless]
  252. ----
  253. <1> def dp = 1;
  254. <2> def dr = new ArrayList();
  255. <3> dr = dp;
  256. ----
  257. +
  258. <1> declare `def dp`;
  259. implicit cast `int 1` to `def` -> `def`;
  260. store `def` to `dp`
  261. <2> declare `def dr`;
  262. allocate `ArrayList` instance -> `ArrayList reference`;
  263. implicit cast `ArrayList reference` to `def` -> `def`;
  264. store `def` to `dr`
  265. <3> load from `dp` -> `def`;
  266. store `def` to `dr`;
  267. (note the switch in the type `dr` represents from `ArrayList` to `int`)
  268. +
  269. * A `def` type value representing the child-most descendant of a value.
  270. +
  271. [source,Painless]
  272. ----
  273. <1> Object l = new ArrayList();
  274. <2> def d = l;
  275. <3> d.ensureCapacity(10);
  276. ----
  277. +
  278. <1> declare `Object l`;
  279. allocate `ArrayList` instance -> `ArrayList reference`;
  280. implicit cast `ArrayList reference` to `Object reference`
  281. -> `Object reference`;
  282. store `Object reference` to `l`
  283. <2> declare `def d`;
  284. load from `l` -> `Object reference`;
  285. implicit cast `Object reference` to `def` -> `def`;
  286. store `def` to `d`;
  287. <3> load from `d` -> `def`;
  288. implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
  289. call `ensureCapacity` on `ArrayList reference` with arguments (`int 10`);
  290. (note `def` was implicit cast to `ArrayList reference`
  291. since ArrayList` is the child-most descendant type value that the
  292. `def` type value represents)
  293. [[string-type]]
  294. ==== String Type
  295. The `String` type is a specialized reference type that does not require
  296. explicit allocation. Use a <<string-literals, string literal>> to directly
  297. evaluate a `String` type value. While not required, the
  298. <<new-instance-operator, new instance operator>> can allocate `String` type
  299. instances.
  300. *Examples*
  301. * General use of the `String` type.
  302. +
  303. [source,Painless]
  304. ----
  305. <1> String r = "some text";
  306. <2> String s = 'some text';
  307. <3> String t = new String("some text");
  308. <4> String u;
  309. ----
  310. +
  311. <1> declare `String r`;
  312. store `String "some text"` to `r`
  313. <2> declare `String s`;
  314. store `String 'some text'` to `s`
  315. <3> declare `String t`;
  316. allocate `String` instance with arguments (`String "some text"`)
  317. -> `String "some text"`;
  318. store `String "some text"` to `t`
  319. <4> declare `String u`;
  320. store default `null` to `u`
  321. [[void-type]]
  322. ==== void Type
  323. The `void` type represents the concept of a lack of type. Use the `void` type to
  324. indicate a function returns no value.
  325. *Examples*
  326. * Use of the `void` type in a function.
  327. +
  328. [source,Painless]
  329. ----
  330. void addToList(List l, def d) {
  331. l.add(d);
  332. }
  333. ----
  334. [[array-type]]
  335. ==== Array Type
  336. An array type is a specialized reference type where an array type instance
  337. contains a series of values allocated to the heap. Each value in an array type
  338. instance is defined as an element. All elements in an array type instance are of
  339. the same type (element type) specified as part of declaration. Each element is
  340. assigned an index within the range `[0, length)` where length is the total
  341. number of elements allocated for an array type instance.
  342. Use the <<new-array-operator, new array operator>> or the
  343. <<array-initialization-operator, array initialization operator>> to allocate an
  344. array type instance. Declare an array type <<painless-variables, variable>> or
  345. access an array type member field (from a reference type instance), and assign
  346. it an array type value for evaluation during later operations. The default value
  347. for a newly-declared array type variable is `null`. An array type value is
  348. shallow-copied during an assignment or as an argument for a method/function
  349. call. Assign `null` to an array type variable to indicate the array type value
  350. refers to no array type instance. The JVM will garbage collect an array type
  351. instance when it is no longer referred to by any array type values. Pass `null`
  352. as an argument to a method/function call to indicate the argument refers to no
  353. array type instance.
  354. Use the <<array-length-operator, array length operator>> to retrieve the length
  355. of an array type value as an `int` type value. Use the
  356. <<array-access-operator, array access operator>> to load from and store to
  357. an individual element within an array type instance.
  358. When an array type instance is allocated with multiple dimensions using the
  359. range `[2, d]` where `d >= 2`, each element within each dimension in the range
  360. `[1, d-1]` is also an array type. The element type of each dimension, `n`, is an
  361. array type with the number of dimensions equal to `d-n`. For example, consider
  362. `int[][][]` with 3 dimensions. Each element in the 3rd dimension, `d-3`, is the
  363. primitive type `int`. Each element in the 2nd dimension, `d-2`, is the array
  364. type `int[]`. And each element in the 1st dimension, `d-1` is the array type
  365. `int[][]`.
  366. *Examples*
  367. * General use of single-dimensional arrays.
  368. +
  369. [source,Painless]
  370. ----
  371. <1> int[] x;
  372. <2> float[] y = new float[10];
  373. <3> def z = new float[5];
  374. <4> y[9] = 1.0F;
  375. <5> z[0] = y[9];
  376. ----
  377. +
  378. <1> declare `int[] x`;
  379. store default `null` to `x`
  380. <2> declare `float[] y`;
  381. allocate `1-d float array` instance with `length [10]`
  382. -> `1-d float array reference`;
  383. store `1-d float array reference` to `y`
  384. <3> declare `def z`;
  385. allocate `1-d float array` instance with `length [5]`
  386. -> `1-d float array reference`;
  387. implicit cast `1-d float array reference` to `def` -> `def`;
  388. store `def` to `z`
  389. <4> load from `y` -> `1-d float array reference`;
  390. store `float 1.0` to `index [9]` of `1-d float array reference`
  391. <5> load from `y` -> `1-d float array reference @0`;
  392. load from `index [9]` of `1-d float array reference @0` -> `float 1.0`;
  393. load from `z` -> `def`;
  394. implicit cast `def` to `1-d float array reference @1`
  395. -> `1-d float array reference @1`;
  396. store `float 1.0` to `index [0]` of `1-d float array reference @1`
  397. +
  398. * General use of a multi-dimensional array.
  399. +
  400. [source,Painless]
  401. ----
  402. <1> int[][][] ia3 = new int[2][3][4];
  403. <2> ia3[1][2][3] = 99;
  404. <3> int i = ia3[1][2][3];
  405. ----
  406. +
  407. <1> declare `int[][][] ia`;
  408. allocate `3-d int array` instance with length `[2, 3, 4]`
  409. -> `3-d int array reference`;
  410. store `3-d int array reference` to `ia3`
  411. <2> load from `ia3` -> `3-d int array reference`;
  412. store `int 99` to `index [1, 2, 3]` of `3-d int array reference`
  413. <3> declare `int i`;
  414. load from `ia3` -> `3-d int array reference`;
  415. load from `index [1, 2, 3]` of `3-d int array reference` -> `int 99`;
  416. store `int 99` to `i`