运算符:参考

编辑

方法调用

编辑

使用 方法调用运算符 '()' 来调用 引用类型值的成员方法。在方法调用期间,会根据需要对每个参数进行隐式装箱/拆箱求值。当对 def 类型值进行方法调用时,参数和返回值类型也会被视为 def 类型,并在运行时进行求值。

重载方法是指与两个或多个方法共享相同名称的方法。方法的重载基于参数个数,即只要参数数量不同,就可以为多个方法重复使用相同的名称。

错误

  • 如果引用类型值为 null
  • 如果给定的引用类型值不存在该成员方法名。
  • 如果传入的参数数量与指定的参数数量不同。
  • 如果参数无法隐式转换为参数的正确类型值或隐式装箱/拆箱为参数的正确类型值。

语法

method_call: '.' ID arguments;
arguments: '(' (expression (',' expression)*)? ')';

示例

  • 对不同引用类型的方法调用。

    Map m = new HashMap();                         
    m.put(1, 2);                                   
    int z = m.get(1);                              
    def d = new ArrayList();                       
    d.add(1);                                      
    int i = Integer.parseInt(d.get(0).toString()); 

    声明 Map m;分配 HashMap 实例 → HashMap 引用;将 HashMap 引用 存储到 m

    m 加载 → Map 引用;隐式将 int 1 转换为 defdef;隐式将 int 2 转换为 defdef;在 Map 引用 上使用参数 (int 1, int 2) 调用 put

    声明 int z;从 m 加载 → Map 引用;在 Map 引用 上使用参数 (int 1) 调用 getdef;隐式将 def 转换为 int 2int 2;将 int 2 存储到 z

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

    d 加载 → def;隐式将 def 转换为 ArrayList 引用ArrayList 引用ArrayList 引用 上使用参数 (int 1) 调用 add

    声明 int i;从 d 加载 → def;隐式将 def 转换为 ArrayList 引用ArrayList 引用ArrayList 引用 上使用参数 (int 1) 调用 getdef;隐式将 def 转换为 Integer 1 引用Integer 1 引用;在 Integer 1 引用 上调用 toStringString '1';在 Integer 上使用参数 (String '1') 调用 parseIntint 1;将 int 1 存储到 i 中;

字段访问

编辑

使用 字段访问运算符 '.' 来存储值到或从 引用类型成员字段加载值。

错误

  • 如果引用类型值为 null
  • 如果给定的引用类型值不存在该成员字段名称。

语法

field_access: '.' ID;

示例

示例使用以下引用类型定义

name:
  Example

non-static member fields:
  * int x
  * def y
  * List z
  • 使用 Example 类型的字段访问。

    Example example = new Example(); 
    example.x = 1;                   
    example.y = example.x;           
    example.z = new ArrayList();     
    example.z.add(1);                
    example.x = example.z.get(0);    

    声明 Example example;分配 Example 实例 → Example 引用;将 Example 引用 存储到 example

    example 加载 → Example 引用;将 int 1 存储到 Example 引用x

    example 加载 → Example 引用 @0;从 example 加载 → Example 引用 @1;从 Example 引用 @1x 加载 → int 1;隐式将 int 1 转换为 defdef;将 def 存储到 Example 引用 @0y;(注意 Example 引用 @0Example 引用 @1 是相同的)

    example 加载 → Example 引用;分配 ArrayList 实例 → ArrayList 引用;隐式将 ArrayList 引用 转换为 List 引用List 引用;将 List 引用 存储到 Example 引用z

    example 加载 → Example 引用;从 Example 引用z 加载 → List 引用;在 List 引用 上使用参数 (int 1) 调用 add

    example 加载 → Example 引用 @0;从 example 加载 → Example 引用 @1;从 Example 引用 @1z 加载 → List 引用;在 List 引用 上使用参数 (int 0) 调用 getint 1;将 int 1 存储到 List 引用 @0x 中;(注意 Example 引用 @0Example 引用 @1 是相同的)

空安全

编辑

使用 空安全运算符 '?.' 而不是方法调用运算符或字段访问运算符,以确保引用类型值在方法调用或字段访问之前为 非 null。如果引用类型值为 null,将返回 null 值,否则将求值方法调用或字段访问。

错误

  • 如果方法调用返回类型值或字段访问类型值不是引用类型值,并且不能隐式转换为引用类型值。

语法

null_safe: null_safe_method_call
         | null_safe_field_access
         ;

null_safe_method_call: '?.' ID arguments;
arguments: '(' (expression (',' expression)*)? ')';

null_safe_field_access: '?.' ID;

示例

示例使用以下引用类型定义

name:
  Example

non-static member methods:
  * List factory()

non-static member fields:
  * List x
  • 没有 null 值的空安全。

    Example example = new Example(); 
    List x = example?.factory();     

    声明 Example example;分配 Example 实例 → Example 引用;将 Example 引用 存储到 example

    声明 List x;从 example 加载 → Example 引用;空安全调用 Example 引用 上的 factoryList 引用;将 List 引用 存储到 x

  • 带有 null 值的空安全;

    Example example = null; 
    List x = example?.x;    

    声明 Example example;将 null 存储到 example

    声明 List x;从 example 加载 → Example 引用;空安全访问 Example 引用 上的 xnull;将 null 存储到 x;(注意,因为 examplenull空安全运算符 返回了 null

列表初始化

编辑

使用 列表初始化运算符 '[]' 在堆上分配一个带有预定义值集的 List 类型实例。用于初始化 List 类型实例的每个值在插入 List 类型实例时,使用 add 方法转换为 def 类型值。将保留指定值的顺序。

语法

list_initialization: '[' expression (',' expression)* ']'
                   | '[' ']';

示例

  • 空的 List 类型值的列表初始化。

    List empty = []; 

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

  • 具有静态值的列表初始化。

    List list = [1, 2, 3]; 

    声明 List list;分配 ArrayList 实例 → ArrayList 引用;在 ArrayList 引用 上使用参数 (int 1) 调用 add;在 ArrayList 引用 上使用参数 (int 2) 调用 add;在 ArrayList 引用 上使用参数 (int 3) 调用 add;隐式将 ArrayList 引用 转换为 List 引用List 引用;将 List 引用 存储到 list

  • 具有非静态值的列表初始化。

    int i = 1;                  
    long l = 2L;                
    float f = 3.0F;             
    double d = 4.0;             
    String s = "5";             
    List list = [i, l, f*d, s]; 

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

    声明 long l;将 long 2 存储到 l

    声明 float f;将 float 3.0 存储到 f

    声明 double d;将 double 4.0 存储到 d

    声明 String s;将 String "5" 存储到 s

    声明 List list;分配 ArrayList 实例 → ArrayList 引用;从 i 加载 → int 1;在 ArrayList 引用 上使用参数 (int 1) 调用 add;从 l 加载 → long 2;在 ArrayList 引用 上使用参数 (long 2) 调用 add;从 f 加载 → float 3.0;从 d 加载 → double 4.0;提升 float 3.0double 4.0:结果 double;隐式将 float 3.0 转换为 double 3.0double 3.0;将 double 3.0double 4.0 相乘 → double 12.0;在 ArrayList 引用 上使用参数 (double 12.0) 调用 add;从 s 加载 → String "5";在 ArrayList 引用 上使用参数 (String "5") 调用 add;隐式将 ArrayList 引用 转换为 List 引用List 引用;将 List 引用 存储到 list

列表访问

编辑

使用 列表访问运算符 '[]' 作为在 List 类型值上进行的 set 方法调用或 get 方法调用的快捷方式。

错误

  • 如果访问的值不是 List 类型值。
  • 如果使用非整数类型值作为 set 方法调用或 get 方法调用的索引。

语法

list_access: '[' expression ']'

示例

  • 使用 List 类型的列表访问。

    List list = new ArrayList(); 
    list.add(1);                 
    list.add(2);                 
    list.add(3);                 
    list[0] = 2;                 
    list[1] = 5;                 
    int x = list[0] + list[1];   
    int y = 1;                   
    int z = list[y];             

    声明 List list; 分配 ArrayList 实例 → ArrayList 引用; 隐式转换 ArrayList 引用List 引用List 引用; 存储 List 引用list

    list 加载 → List 引用; 在 List 引用 上调用 add,参数为(int 1)

    list 加载 → List 引用; 在 List 引用 上调用 add,参数为(int 2)

    list 加载 → List 引用; 在 List 引用 上调用 add,参数为(int 3)

    list 加载 → List 引用; 在 List 引用 上调用 set,参数为(int 0, int 2)

    list 加载 → List 引用; 在 List 引用 上调用 set,参数为(int 1, int 5)

    声明 int x; 从 list 加载 → List 引用; 在 List 引用 上调用 get,参数为(int 0) → def; 隐式转换 defint 2int 2; 从 list 加载 → List 引用; 在 List 引用 上调用 get,参数为(int 1) → def; 隐式转换 defint 5int 5; 将 int 2int 5 相加 → int 7; 存储 int 7x

    声明 int y; 存储 int 1y

    声明 int z; 从 list 加载 → List 引用; 从 y 加载 → int 1; 在 List 引用 上调用 get,参数为(int 1) → def; 隐式转换 defint 5int 5; 存储 int 5z

  • 使用 def 类型访问 List。

    def d = new ArrayList(); 
    d.add(1);                
    d.add(2);                
    d.add(3);                
    d[0] = 2;                
    d[1] = 5;                
    def x = d[0] + d[1];     
    def y = 1;               
    def z = d[y];            

    声明 List d; 分配 ArrayList 实例 → ArrayList 引用; 隐式转换 ArrayList 引用defdef; 存储 defd

    d 加载 → def; 隐式转换 defArrayList 引用ArrayList 引用; 在 ArrayList 引用 上调用 add,参数为(int 1)

    d 加载 → def; 隐式转换 defArrayList 引用ArrayList 引用; 在 ArrayList 引用 上调用 add,参数为(int 2)

    d 加载 → def; 隐式转换 defArrayList 引用ArrayList 引用; 在 ArrayList 引用 上调用 add,参数为(int 3)

    d 加载 → def; 隐式转换 defArrayList 引用ArrayList 引用; 在 ArrayList 引用 上调用 set,参数为(int 0, int 2)

    d 加载 → def; 隐式转换 defArrayList 引用ArrayList 引用; 在 ArrayList 引用 上调用 set,参数为(int 1, int 5)

    声明 def x; 从 d 加载 → def; 隐式转换 defArrayList 引用ArrayList 引用; 在 ArrayList 引用 上调用 get,参数为(int 0) → def; 隐式转换 defint 2int 2; 从 d 加载 → def; 隐式转换 defArrayList 引用ArrayList 引用; 在 ArrayList 引用 上调用 get,参数为(int 1) → def; 隐式转换 defint 2int 2; 将 int 2int 5 相加 → int 7; 存储 int 7x

    声明 int y; 存储 int 1y

    声明 int z; 从 d 加载 → ArrayList 引用; 从 y 加载 → def; 隐式转换 defint 1int 1; 在 ArrayList 引用 上调用 get,参数为(int 1) → def; 存储 defz

Map 初始化

编辑

使用 map 初始化运算符 '[:]' 在堆上分配一个 Map 类型实例,并带有一组预定义的值。用于初始化 Map 类型实例的每对值,在使用 put 方法插入 Map 类型实例时,都会被转换为 def 类型的值。

语法

map_initialization: '[' key_pair (',' key_pair)* ']'
                  | '[' ':' ']';
key_pair: expression ':' expression

示例

  • 初始化一个空的 Map 类型值。

    Map empty = [:]; 

    声明 Map empty; 分配 HashMap 实例 → HashMap 引用; 隐式转换 HashMap 引用Map 引用Map 引用; 存储 Map 引用empty

  • 使用静态值初始化 Map。

    Map map = [1:2, 3:4, 5:6]; 

    声明 Map map; 分配 HashMap 实例 → HashMap 引用; 在 HashMap 引用 上调用 put,参数为(int 1, int 2); 在 HashMap 引用 上调用 put,参数为(int 3, int 4); 在 HashMap 引用 上调用 put,参数为(int 5, int 6); 隐式转换 HashMap 引用Map 引用Map 引用; 存储 Map 引用map

  • 使用非静态值初始化 Map。

    byte b = 0;                  
    int i = 1;                   
    long l = 2L;                 
    float f = 3.0F;              
    double d = 4.0;              
    String s = "5";              
    Map map = [b:i, l:f*d, d:s]; 

    声明 byte b; 存储 byte 0b

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

    声明 long l;将 long 2 存储到 l

    声明 float f;将 float 3.0 存储到 f

    声明 double d;将 double 4.0 存储到 d

    声明 String s;将 String "5" 存储到 s

    声明 Map map; 分配 HashMap 实例 → HashMap 引用; 从 b 加载 → byte 0; 从 i 加载 → int 1; 在 HashMap 引用 上调用 put,参数为(byte 0, int 1); 从 l 加载 → long 2; 从 f 加载 → float 3.0; 从 d 加载 → double 4.0; 提升 float 3.0double 4.0: 结果为 double; 隐式转换 float 3.0double 3.0double 3.0; 将 double 3.0double 4.0 相乘 → double 12.0; 在 HashMap 引用 上调用 put,参数为(long 2, double 12.0); 从 d 加载 → double 4.0; 从 s 加载 → String "5"; 在 HashMap 引用 上调用 put,参数为(double 4.0, String "5"); 隐式转换 HashMap 引用Map 引用Map 引用; 存储 Map 引用map

Map 访问

编辑

使用 map 访问运算符 '[]' 作为对 Map 类型值进行 put 方法调用或 get 方法调用的快捷方式。

错误

  • 如果访问的值不是 Map 类型值。

语法

map_access: '[' expression ']'

示例

  • 使用 Map 类型进行 Map 访问。

    Map map = new HashMap();               
    map['value2'] = 2;                     
    map['value5'] = 5;                     
    int x = map['value2'] + map['value5']; 
    String y = 'value5';                   
    int z = x[z];                          

    声明 Map map; 分配 HashMap 实例 → HashMap 引用; 隐式转换 HashMap 引用Map 引用Map 引用; 存储 Map 引用map

    map 加载 → Map 引用; 在 Map 引用 上调用 put,参数为(String 'value2', int 2)

    map 加载 → Map 引用; 在 Map 引用 上调用 put,参数为(String 'value5', int 5)

    声明 int x; 从 map 加载 → Map 引用; 在 Map 引用 上调用 get,参数为(String 'value2') → def; 隐式转换 defint 2int 2; 从 map 加载 → Map 引用; 在 Map 引用 上调用 get,参数为(String 'value5') → def; 隐式转换 defint 5int 5; 将 int 2int 5 相加 → int 7; 存储 int 7x

    声明 String y; 存储 String 'value5'y

    声明 int z; 从 map 加载 → Map 引用; 从 y 加载 → String 'value5'; 在 Map 引用 上调用 get,参数为(String 'value5') → def; 隐式转换 defint 5int 5; 存储 int 5z

  • 使用 def 类型进行 Map 访问。

    def d = new HashMap();             
    d['value2'] = 2;                   
    d['value5'] = 5;                   
    int x = d['value2'] + d['value5']; 
    String y = 'value5';               
    def z = d[y];                      

    声明 def d; 分配 HashMap 实例 → HashMap 引用; 隐式转换 HashMap 引用defdef; 存储 defd

    d 加载 → def; 隐式转换 defHashMap 引用HashMap 引用; 在 HashMap 引用 上调用 put,参数为(String 'value2', int 2)

    d 加载 → def;隐式转换 defHashMap 引用HashMap 引用;在 HashMap 引用 上调用 put 方法,参数为 (String 'value5', int 5)

    声明 int x;从 d 加载 → def;隐式转换 defHashMap 引用HashMap 引用;在 HashMap 引用 上调用 get 方法,参数为 (String 'value2') → def;隐式转换 defint 2int 2;从 d 加载 → def;在 HashMap 引用 上调用 get 方法,参数为 (String 'value5') → def;隐式转换 defint 5int 5;将 int 2int 5 相加 → int 7;将 int 7 存储到 x

    声明 String y; 存储 String 'value5'y

    声明 def z;从 d 加载 → def;从 y 加载 → String 'value5';在 HashMap 引用 上调用 get 方法,参数为 (String 'value5') → def;将 def 存储到 z

新实例操作符

编辑

使用 新实例操作符 'new ()' 在堆上分配一个 引用类型 实例,并调用指定的构造函数。在构造函数调用期间,会根据需要对每个参数进行隐式 装箱/拆箱

重载的构造函数是指与两个或多个构造函数共享相同名称的构造函数。构造函数基于参数数量进行重载,其中只要参数数量不同,相同的引用类型名称就可以用于多个构造函数。

错误

  • 如果实例分配的引用类型名称不存在。
  • 如果传入的参数数量与指定的参数数量不同。
  • 如果参数无法隐式转换为参数的正确类型值或隐式装箱/拆箱为参数的正确类型值。

语法

new_instance: 'new' TYPE '(' (expression (',' expression)*)? ')';

示例

  • 分配不同类型的新实例。
Map m = new HashMap();   
def d = new ArrayList(); 
def e = new HashMap(m);  

声明 Map m;分配 HashMap 实例 → HashMap 引用;隐式转换 HashMap 引用Map 引用Map 引用;将 Map 引用 存储到 m

声明 def d;分配 ArrayList 实例 → ArrayList 引用;隐式转换 ArrayList 引用defdef;将 def 存储到 d

声明 def e;从 m 加载 → Map 引用;分配一个带有参数 (Map 引用) 的 HashMap 实例 → HashMap 引用;隐式转换 HashMap 引用defdef;将 def 存储到 e

字符串连接

编辑

使用 字符串连接操作符 '+' 将两个值连接在一起,其中至少一个值是 String 类型

语法

concatenate: expression '+' expression;

示例

  • 字符串与不同原始类型连接。

    String x = "con";     
    String y = x + "cat"; 
    String z = 4 + 5 + x; 

    声明 String x;将 String "con" 存储到 x

    声明 String y;从 x 加载 → String "con";连接 String "con"String "cat"String "concat";将 String "concat" 存储到 y

    声明 String z;将 int 4int 5 相加 → int 9;连接 int 9String "9concat";将 String "9concat" 存储到 z;(注意,由于特定操作的优先级和结合性,加法运算在连接之前完成)

  • 字符串与 def 类型连接。

    def d = 2;             
    d = "con" + d + "cat"; 

    声明 def;隐式转换 int 2defdef;将 def 存储到 d

    连接 String "con"int 2String "con2";连接 String "con2"String "cat"String "con2cat";隐式转换 String "con2cat"defdef;将 def 存储到 d;(注意 d 的类型从 int 切换到 String

Elvis 操作符

编辑

Elvis 操作符包含两个表达式。首先评估第一个表达式以检查是否存在 null 值。如果第一个表达式评估为 null,则评估第二个表达式并使用其值。如果第一个表达式评估为 非 null,则使用第一个表达式的结果值。使用 elvis 操作符 '?:' 作为条件操作符的快捷方式。

错误

  • 如果第一个或第二个表达式不能产生 null 值。

语法

elvis: expression '?:' expression;

示例

  • Elvis 操作符与不同的引用类型一起使用。

    List x = new ArrayList();      
    List y = x ?: new ArrayList(); 
    y = null;                      
    List z = y ?: new ArrayList(); 

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

    声明 List y;加载 xList 引用List 引用 等于 nullfalse;评估第一个表达式:List 引用List 引用;将 List 引用 存储到 y

    null 存储到 y

    声明 List z;加载 yList 引用List 引用 等于 nulltrue;评估第二个表达式:分配 ArrayList 实例 → ArrayList 引用;隐式转换 ArrayList 引用List 引用List 引用;将 List 引用 存储到 z