类型编辑

类型是对数据的分类,用于定义值的属性。这些属性指定值表示的数据以及在 操作 期间评估值的规则。每个类型都属于以下类别之一:基本类型引用类型动态类型

基本类型编辑

基本类型表示 JVM 本身构建的基本数据,并分配给非堆内存。声明基本类型 变量 或访问基本类型成员字段(来自引用类型实例),并为其分配基本类型值以在以后的操作期间进行评估。新声明的基本类型变量的默认值列在以下定义中。在赋值或作为方法/函数调用的参数时,基本类型值会被复制。

基本类型具有相应的引用类型(也称为装箱类型)。对基本类型值使用 字段访问运算符方法调用运算符 以强制将其评估为其相应的引用类型值。

以下基本类型可用。相应的引用类型列在括号中。例如,Bytebyte 基本类型的引用类型

可用的基本类型
byte (Byte)
8 位、带符号、二进制补码整数。范围: [-128, 127]。默认值: 0
short (Short)
16 位、带符号、二进制补码整数。范围: [-32768, 32767]。默认值: 0
char (Character)
16 位、无符号、Unicode 字符。范围: [0, 65535]。默认值: 0\u0000
int (Integer)
32 位、带符号、二进制补码整数。范围: [-2^31, 2^31-1]。默认值: 0
long (Long)
64 位、带符号、二进制补码整数。范围: [-2^63, 2^63-1]。默认值: 0
float (`Float)`
32 位、带符号、单精度、IEEE 754 浮点数。默认值 0.0
double (Double)
64 位、带符号、双精度、IEEE 754 浮点数。默认值: 0.0
boolean (Boolean)
逻辑量,具有 truefalse 两个可能的值。默认值: false

示例

  • 在声明、声明和赋值中使用的基本类型。

    int i = 1;        
    double d;         
    boolean b = true; 

    声明 int i;将 int 1 存储到 i

    声明 double d;将默认 double 0.0 存储到 d

    声明 boolean b;将 boolean true 存储到 b

  • 使用相应引用类型对基本类型进行方法调用。

    int i = 1;    
    i.toString(); 

    声明 int i;将 int 1 存储到 i

    i 加载 → int 1;将 int 1 装箱 → Integer 1 引用;对 Integer 1 引用 调用 toStringString '1'

引用类型编辑

引用类型是命名构造(对象),可能表示多个数据片段(成员字段)和用于操作这些数据的逻辑(成员方法),定义为脚本应用程序编程接口 (API) 的一部分。

引用类型实例是分配给堆的一个引用类型对象的单个数据集。使用 新建实例运算符 来分配引用类型实例。使用引用类型实例来加载、存储和操作复杂数据。

引用类型值引用引用类型实例,多个引用类型值可能引用同一个引用类型实例。对引用类型实例的更改将影响引用该特定实例的所有引用类型值。

声明引用类型 变量 或访问引用类型成员字段(来自引用类型实例),并为其分配引用类型值以在以后的操作期间进行评估。新声明的引用类型变量的默认值为 null。在赋值或作为方法/函数调用的参数时,引用类型值会被浅复制。将 null 分配给引用类型变量以指示引用类型值不引用任何引用类型实例。当不再有任何引用类型值引用引用类型实例时,JVM 将对其进行垃圾回收。将 null 作为参数传递给方法/函数调用以指示该参数不引用任何引用类型实例。

引用类型对象定义了以下内容的零到多个

静态成员字段
静态成员字段是命名和类型化的数据片段。每个引用类型 对象 包含一组代表其静态成员字段的数据。使用 字段访问运算符 与引用类型对象名称相对应以访问静态成员字段,以便加载和存储到特定引用类型 对象 中。无需分配引用类型实例即可使用静态成员字段。
非静态成员字段
非静态成员字段是命名和类型化的数据片段。每个引用类型 实例 包含一组代表其引用类型对象的非静态成员字段的数据。使用 字段访问运算符 来加载和存储到特定引用类型 实例 的非静态成员字段中。使用非静态成员字段需要分配引用类型实例。
静态成员方法
静态成员方法是在引用类型 对象 上调用的 函数。使用 方法调用运算符 与引用类型对象名称相对应以调用静态成员方法。无需分配引用类型实例即可使用静态成员方法。
非静态成员方法
非静态成员方法是在引用类型 实例 上调用的 函数。在引用类型实例上调用的非静态成员方法可以加载和存储到该特定引用类型实例的非静态成员字段中。使用 方法调用运算符 与特定引用类型实例相对应以调用非静态成员方法。使用非静态成员方法需要分配引用类型实例。
构造函数
构造函数是一种特殊的 函数,用于分配由特定引用类型 对象 定义的引用类型 实例。使用 新建实例运算符 来分配引用类型实例。

引用类型对象遵循基本继承模型。考虑类型 A 和 B。如果 B 继承了 A 的所有非静态成员(能够将其作为自己的成员访问),则类型 A 被认为是 B 的父类型,B 被认为是 A 的子类型。如果从 B 到 A 存在一个递归的父子关系,其中间存在零到多个类型,则类型 B 被认为是 A 的后代。在这种情况下,B 继承了 A 的所有非静态成员以及中间类型的所有非静态成员。在这两种关系中,类型 B 也被认为是类型 A。

示例

  • 在几种不同的操作中评估引用类型。

    List l = new ArrayList(); 
    l.add(1);                 
    int i = l.get(0) + 2;     

    声明 List l;分配 ArrayList 实例 → ArrayList 引用;将 ArrayList 引用 隐式转换为 List 引用List 引用;将 List 引用 存储到 l

    l 加载 → List 引用;将 int 1 隐式转换为 defdef;使用参数 (def) 对 List 引用 调用 add

    声明 int i;从 l 加载 → List 引用;使用参数 (int 0) 对 List 引用 调用 getdef;将 def 隐式转换为 int 1int 1;将 int 1int 2 相加 → int 3;将 int 3 存储到 i

  • 共享引用类型实例。

    List l0 = new ArrayList();     
    List l1 = l0;                  
    l0.add(1);                     
    l1.add(2);                     
    int i = l1.get(0) + l0.get(1); 

    声明 List l0;分配 ArrayList 实例 → ArrayList 引用;将 ArrayList 引用 隐式转换为 List 引用List 引用;将 List 引用 存储到 l0

    声明 List l1;从 l0 加载到 List reference;将 List reference 存储到 l1(注意 l0l1 指向同一个实例,称为浅拷贝)

    l0 加载到 List reference;隐式将 int 1 转换为 defdef 调用 List reference 上的 add 方法,参数为 (def)

    l1 加载到 List reference;隐式将 int 2 转换为 defdef 调用 List reference 上的 add 方法,参数为 (def)

    声明 int i;从 l0 加载到 List reference;调用 List reference 上的 get 方法,参数为 (int 0) → def @0;隐式将 def @0 转换为 int 1int 1;从 l1 加载到 List reference;调用 List reference 上的 get 方法,参数为 (int 1) → def @1;隐式将 def @1 转换为 int 2int 2;将 int 1int 2 相加 → int 3;将 int 3 存储到 i 中;

  • 使用引用类型的静态成员。

    int i = Integer.MAX_VALUE;       
    long l = Long.parseLong("123L"); 

    声明 int i;从 Integer 上的 MAX_VALUE 加载 → int 2147483647;将 int 2147483647 存储到 i

    声明 long l;调用 Long 上的 parseLong 方法,参数为 (long 123) → long 123;将 long 123 存储到 l

动态类型edit

动态类型值可以使用单个类型名称 def 来表示任何基本类型或引用类型的值。 def 类型值模拟了它在运行时所代表的值的行为,并且在操作期间评估时,它将始终代表任何类型值的子代类型值。

声明一个 def 类型的 变量 或访问一个 def 类型的成员字段(来自引用类型实例),并为其分配任何类型的值,以便在以后的操作期间进行评估。新声明的 def 类型变量的默认值为 nulldef 类型变量或方法/函数参数可以在脚本的编译和评估期间更改它所代表的类型。

使用 def 类型可能会对性能产生轻微的影响。当性能至关重要时,请直接使用基本类型和引用类型。

错误

  • 如果 def 类型值在运行时代表了不适合操作评估的类型。

示例

  • def 类型的通用用法。

    def dp = 1;               
    def dr = new ArrayList(); 
    dr = dp;                  

    声明 def dp;隐式将 int 1 转换为 defdef;将 def 存储到 dp

    声明 def dr;分配 ArrayList 实例 → ArrayList reference;隐式将 ArrayList reference 转换为 defdef;将 def 存储到 dr

    dp 加载到 def;将 def 存储到 dr 中;(注意 dr 所代表的类型从 ArrayList 切换到 int

  • 一个 def 类型值,代表值的子代类型。

    Object l = new ArrayList(); 
    def d = l;                  
    d.ensureCapacity(10);       

    声明 Object l;分配 ArrayList 实例 → ArrayList reference;隐式将 ArrayList reference 转换为 Object referenceObject reference;将 Object reference 存储到 l

    声明 def d;从 l 加载到 Object reference;隐式将 Object reference 转换为 defdef;将 def 存储到 d 中;

    d 加载到 def;隐式将 def 转换为 ArrayList referenceArrayList reference;调用 ArrayList reference 上的 ensureCapacity 方法,参数为 (int 10);(注意 def 被隐式转换为 ArrayList reference,因为 ArrayListdef 类型值所代表的子代类型值)

字符串类型edit

String 类型是一种特殊的引用类型,不需要显式分配。使用 字符串字面量 直接评估 String 类型的值。虽然不是必需的,但可以使用 新建实例运算符 来分配 String 类型实例。

示例

  • String 类型的通用用法。

    String r = "some text";             
    String s = 'some text';             
    String t = new String("some text"); 
    String u;                           

    声明 String r;将 String "some text" 存储到 r

    声明 String s;将 String 'some text' 存储到 s

    声明 String t;分配 String 实例,参数为 (String "some text") → String "some text";将 String "some text" 存储到 t

    声明 String u;将默认值 null 存储到 u

void 类型edit

void 类型表示缺乏类型的概念。使用 void 类型来指示函数不返回值。

示例

  • 在函数中使用 void 类型。

    void addToList(List l, def d) {
        l.add(d);
    }

数组类型edit

数组类型是一种特殊的引用类型,其中数组类型实例包含一系列分配到堆中的值。数组类型实例中的每个值都被定义为一个元素。数组类型实例中的所有元素都具有相同的类型(元素类型),该类型在声明中指定。每个元素在范围内被分配一个索引 [0, length),其中 length 是为数组类型实例分配的元素总数。

使用 新建数组运算符数组初始化运算符 来分配数组类型实例。声明一个数组类型的 变量 或访问一个数组类型的成员字段(来自引用类型实例),并为其分配一个数组类型值,以便在以后的操作期间进行评估。新声明的数组类型变量的默认值为 null。数组类型值在赋值或作为方法/函数调用参数时被浅拷贝。将 null 分配给数组类型变量以指示数组类型值不引用任何数组类型实例。当不再有任何数组类型值引用数组类型实例时,JVM 将对其进行垃圾回收。将 null 作为参数传递给方法/函数调用以指示该参数不引用任何数组类型实例。

使用 数组长度运算符int 类型值的形式检索数组类型值的长度。使用 数组访问运算符 从数组类型实例中的单个元素加载和存储。

当使用范围 [2, d](其中 d >= 2)分配具有多个维度的数组类型实例时,范围内每个维度中的每个元素 [1, d-1] 也是一个数组类型。每个维度 n 的元素类型是一个数组类型,其维度数等于 d-n。例如,考虑具有 3 个维度的 int[][][]。第三维 d-3 中的每个元素都是基本类型 int。第二维 d-2 中的每个元素都是数组类型 int[]。第一维 d-1 中的每个元素都是数组类型 int[][]

示例

  • 一维数组的通用用法。

    int[] x;                   
    float[] y = new float[10]; 
    def z = new float[5];      
    y[9] = 1.0F;               
    z[0] = y[9];               

    声明 int[] x;将默认值 null 存储到 x

    声明 float[] y;分配 1-d float array 实例,长度为 [10]1-d float array reference;将 1-d float array reference 存储到 y

    声明 def z;分配 1-d float array 实例,长度为 [5]1-d float array reference;隐式将 1-d float array reference 转换为 defdef;将 def 存储到 z

    y 加载到 1-d float array reference;将 float 1.0 存储到 1-d float array referenceindex [9]

    y 加载到 1-d float array reference @0;从 1-d float array reference @0index [9] 加载到 float 1.0;从 z 加载到 def;隐式将 def 转换为 1-d float array reference @11-d float array reference @1;将 float 1.0 存储到 1-d float array reference @1index [0]

  • 多维数组的通用用法。

    int[][][] ia3 = new int[2][3][4]; 
    ia3[1][2][3] = 99;                
    int i = ia3[1][2][3];             

    声明 int[][][] ia;分配 3-d int array 实例,长度为 [2, 3, 4]3-d int array reference;将 3-d int array reference 存储到 ia3

    ia3 加载到 3-d int array reference;将 int 99 存储到 3-d int array referenceindex [1, 2, 3]

    声明 int i;从 ia3 加载到 3-d int array reference;从 3-d int array referenceindex [1, 2, 3] 加载到 int 99;将 int 99 存储到 i