﻿---
title: Types
description: A type is a classification of data used to define the properties of a value. These properties specify what data a value represents and the rules for how...
url: https://www.elastic.co/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-types
products:
  - Elasticsearch
  - Painless
applies_to:
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Generally available
---

# Types
A type is a classification of data used to define the properties of a value. These properties specify what data a value represents and the rules for how a value is evaluated during an [operation](https://www.elastic.co/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators). Each type belongs to one of the following categories: [primitive](#primitive-types), [reference](#reference-types), or [dynamic](#dynamic-types).

## Primitive types

A primitive type represents basic data built natively into the JVM and is allocated to non-heap memory. Declare a primitive type [variable](https://www.elastic.co/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-variables) or access a primitive type member field (from a reference type instance), and assign it a primitive type value for evaluation during later operations. The default value for a newly-declared primitive type variable is listed as part of the definitions below. A primitive type value is copied during an assignment or as an argument for a method/function call.
A primitive type has a corresponding reference type (also known as a boxed type). Use the [field access operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-reference#field-access-operator) or [method call operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-reference#method-call-operator) on a primitive type value to force evaluation as its corresponding reference type value.
The following primitive types are available. The corresponding reference type is listed in parentheses. For example, `Byte` is the reference type for the `byte` primitive type:
<dropdown title="Available primitive types">
  <definitions>
    <definition term="byte (Byte)">
      8-bit, signed, two’s complement integer. Range: [`-128`, `127`]. Default: `0`.
    </definition>
    <definition term="short (Short)">
      16-bit, signed, two’s complement integer. Range: [`-32768`, `32767`]. Default: `0`.
    </definition>
    <definition term="char (Character)">
      16-bit, unsigned, Unicode character. Range: [`0`, `65535`]. Default: `0` or `\u0000`.
    </definition>
    <definition term="int (Integer)">
      32-bit, signed, two’s complement integer. Range: [`-2^31`, `2^31 - 1`]. Default: `0`.
    </definition>
    <definition term="long (Long)">
      64-bit, signed, two’s complement integer. Range: [`-2^63`, `2^63 - 1`]. Default: `0`.
    </definition>
    <definition term="float (Float)">
      32-bit, signed, single-precision, IEEE 754 floating point number. Default `0.0`.
    </definition>
    <definition term="double (Double)">
      64-bit, signed, double-precision, IEEE 754 floating point number. Default: `0.0`.
    </definition>
    <definition term="boolean (Boolean)">
      logical quantity with two possible values of `true` and `false`. Default: `false`.
    </definition>
  </definitions>
</dropdown>

**Examples**
- Primitive types used in declaration, declaration and assignment
  ```java
  int i = 1;        
  double d;         
  boolean b = true; 
  ```
- Method call on a primitive type using the corresponding reference type
  ```java
  int i = 1;    
  i.toString(); 
  ```


## Character type usage

The `char` type is a 16-bit, unsigned, Unicode character with a range of [`0`,`65535`] and a default value of `0` or `\u0000`.
Character values cannot be declared without an explicit cast from a string.
```
// This will cause an error
 char x = "a"; 

// Must always cast 
char x = (char) "a";
```


### String to character casting

Use the cast operator to convert a [string-type](#string-type) value into a `char`-type value.
**Errors**
- If the `String` type value isn’t one character in length.
- If the `String` type value is `null`.

**Examples**
- Casting string literals into `char` type values
  ```
  char c = (char)"C"; // declare char c; explicit cast String "C" to char C → char C; store char C to c
  c = (char)'c';     
  ```
- Casting a `String` reference into a `char` type value
  ```
  String s = "s";   // declare String s; store String "s" to s
  char c = (char)s; // declare char c; load from s → String "s"; explicit cast String "s" to char s → char s; store char s to c
  ```
- Working with character positions in strings
  ```
  String word = "Hello";
  char first = (char) word.charAt(0);
  char third = (char) word.charAt(2);
  ```


### Character to string casting

Use the cast operator to convert a `char` type value into a [`String` type](#string-type) value.
**Examples**
- Casting a `char` to a `String`
  ```
  char c = 65;         
  String s = (String)c;
  ```


## Reference types

A reference type is a named construct (object), potentially representing multiple pieces of data (member fields) and logic to manipulate that data (member methods), defined as part of the application programming interface (API) for scripts.
A reference type instance is a single set of data for one reference type object allocated to the heap. Use the [new instance operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-reference#new-instance-operator) to allocate a reference type instance. Use a reference type instance to load from, store to, and manipulate complex data.
A reference type value refers to a reference type instance, and multiple reference type values may refer to the same reference type instance. A change to a reference type instance will affect all reference type values referring to that specific instance.
Declare a reference type [variable](https://www.elastic.co/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-variables) or access a reference type member field (from a reference type instance), and assign it a reference type value for evaluation during later operations. The default value for a newly-declared reference type variable is `null`. A reference type value is shallow-copied during an assignment or as an argument for a method/function call. Assign `null` to a reference type variable to indicate the reference type value refers to no reference type instance. The JVM will garbage collect a reference type instance when it is no longer referred to by any reference type values. Pass `null` as an argument to a method/function call to indicate the argument refers to no reference type instance.
A reference type object defines zero-to-many of each of the following:
<definitions>
  <definition term="static member field">
    A static member field is a named and typed piece of data. Each reference type **object** contains one set of data representative of its static member fields. Use the [field access operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-reference#field-access-operator) in correspondence with the reference type object name to access a static member field for loading and storing to a specific reference type **object**. No reference type instance allocation is necessary to use a static member field.
  </definition>
  <definition term="non-static member field">
    A non-static member field is a named and typed piece of data. Each reference type **instance** contains one set of data representative of its reference type object’s non-static member fields. Use the [field access operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-reference#field-access-operator) for loading and storing to a non-static member field of a specific reference type **instance**. An allocated reference type instance is required to use a non-static member field.
  </definition>
  <definition term="static member method">
    A static member method is a [function](https://www.elastic.co/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-functions) called on a reference type **object**. Use the [method call operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-reference#method-call-operator) in correspondence with the reference type object name to call a static member method. No reference type instance allocation is necessary to use a static member method.
  </definition>
  <definition term="non-static member method">
    A non-static member method is a [function](https://www.elastic.co/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-functions) called on a reference type **instance**. A non-static member method called on a reference type instance can load from and store to non-static member fields of that specific reference type instance. Use the [method call operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-reference#method-call-operator) in correspondence with a specific reference type instance to call a non-static member method. An allocated reference type instance is required to use a non-static member method.
  </definition>
  <definition term="constructor">
    A constructor is a special type of [function](https://www.elastic.co/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-functions) used to allocate a reference type **instance** defined by a specific reference type **object**. Use the [new instance operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-reference#new-instance-operator) to allocate a reference type instance.
  </definition>
</definitions>

A reference type object follows a basic inheritance model. Consider types A and B. Type A is considered to be a parent of B, and B a child of A, if B inherits (is able to access as its own) all of A’s non-static members. Type B is considered a descendant of A if there exists a recursive parent-child relationship from B to A with none to many types in between. In this case, B inherits all of A’s non-static members along with all of the non-static members of the types in between. Type B is also considered to be a type A in both relationships.
**Examples**
- Reference types evaluated in several different operations
  ```java
  List l = new ArrayList(); 
  l.add(1);                 
  int i = l.get(0) + 2;     
  ```
- Sharing a reference type instance.
  ```java
  List l0 = new ArrayList();     
  List l1 = l0;                  
  l0.add(1);                     
  l1.add(2);                     
  int i = l1.get(0) + l0.get(1); 
  ```
- Using the static members of a reference type
  ```java
  int i = Integer.MAX_VALUE;       
  long l = Long.parseLong("123L"); 
  ```


## Dynamic types

A dynamic type value can represent the value of any primitive type or reference type using a single type name `def`. A `def` type value mimics the behavior of whatever value it represents at run-time and will always represent the child-most descendant type value of any type value when evaluated during operations.
Declare a `def` type [variable](https://www.elastic.co/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-variables) or access a `def` type member field (from a reference type instance), and assign it any type of value for evaluation during later operations. The default value for a newly-declared `def` type variable is `null`. A `def` type variable or method/function parameter can change the type it represents during the compilation and evaluation of a script.
Using the `def` type can have a slight impact on performance. Use only primitive types and reference types directly when performance is critical.
**Errors**
- If a `def` type value represents an inappropriate type for evaluation of an operation at run-time.

**Examples**
- General uses of the `def` type
  ```java
  def dp = 1;               
  def dr = new ArrayList(); 
  dr = dp;                  
  ```
- A `def` type value representing the child-most descendant of a value.
  ```java
  Object l = new ArrayList(); 
  def d = l;                  
  d.ensureCapacity(10);       
  ```


## String type

The `String` type is a specialized reference type that does not require explicit allocation. Use a [string literal](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-literals#string-literals) to directly evaluate a `String` type value. While not required, the [new instance operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-reference#new-instance-operator) can allocate `String` type instances.
**Examples**
- General use of the `String` type
  ```java
  String r = "some text";             
  String s = 'some text';             
  String t = new String("some text"); 
  String u;                           
  ```


## Void type

The `void` type represents the concept of a lack of type. Use the `void` type to indicate a function returns no value.
**Examples**
- Use of the `void` type in a function
  ```java
  void addToList(List l, def d) {
      l.add(d);
  }
  ```


## Array type

An array type is a specialized reference type where an array type instance contains a series of values allocated to the heap. Each value in an array type instance is defined as an element. All elements in an array type instance are of the same type (element type) specified as part of declaration. Each element is assigned an index within the range `[0, length)` where length is the total number of elements allocated for an array type instance.
Use the [new array operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-array#new-array-operator) or the [array initialization operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-array#array-initialization-operator) to allocate an array type instance. Declare an array type [variable](https://www.elastic.co/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-variables) or access an array type member field (from a reference type instance), and assign it an array type value for evaluation during later operations. The default value for a newly-declared array type variable is `null`. An array type value is shallow-copied during an assignment or as an argument for a method/function call. Assign `null` to an array type variable to indicate the array type value refers to no array type instance. The JVM will garbage collect an array type instance when it is no longer referred to by any array type values. Pass `null` as an argument to a method/function call to indicate the argument refers to no array type instance.
Use the [array length operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-array#array-length-operator) to retrieve the length of an array type value as an `int` type value. Use the [array access operator](/elastic/docs-builder/docs/2777/reference/scripting-languages/painless/painless-operators-array#array-access-operator) to load from and store to an individual element within an array type instance.
When an array type instance is allocated with multiple dimensions using the range `[2, d]` where `d >= 2`, each element within each dimension in the range `[1, d-1]` is also an array type. The element type of each dimension, `n`, is an array type with the number of dimensions equal to `d-n`. For example, consider `int[][][]` with 3 dimensions. Each element in the 3rd dimension, `d-3`, is the primitive type `int`. Each element in the 2nd dimension, `d-2`, is the array type `int[]`. And each element in the 1st dimension, `d-1` is the array type `int[][]`.
**Examples**
- General use of single-dimensional arrays
  ```java
  int[] x;                   
  float[] y = new float[10]; 
  def z = new float[5];      
  y[9] = 1.0F;               
  z[0] = y[9];               
  ```
- General use of a multi-dimensional array
  ```java
  int[][][] ia3 = new int[2][3][4]; 
  ia3[1][2][3] = 99;                
  int i = ia3[1][2][3];             
  ```