运算符:参考编辑

方法调用编辑

使用 方法调用运算符 '()'引用类型 值上调用成员方法。在方法调用期间,根据参数需要进行隐式 装箱/拆箱。当对目标 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;使用参数 (int 1, int 2) 在 Map 引用 上调用 put

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

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

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

    声明 int i;从 d 加载 → def;隐式将 def 转换为 ArrayList 引用ArrayList 引用 使用参数 (int 1) 在 ArrayList 引用 上调用 getdef;隐式将 def 转换为 Integer 1 引用Integer 1 引用;在 Integer 1 引用 上调用 toStringString '1';使用参数 (String '1') 在 Integer 上调用 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 引用;使用参数 (int 1) 在 List 引用 上调用 add

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

空安全编辑

使用 空安全运算符 '?.' 而不是方法调用运算符或字段访问运算符,以确保引用类型值在方法调用或字段访问之前为 非空。如果引用类型值为 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 中;(注意 空安全运算符 返回了 null,因为 examplenull

列表初始化编辑

使用 列表初始化运算符 '[]' 在堆上分配一个具有预定义值的 List 类型实例。用于初始化 List 类型实例的每个值在使用 add 方法插入到 List 类型实例时都会被转换为 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 引用;使用参数 (int 1) 在 ArrayList 引用 上调用 add;使用参数 (int 2) 在 ArrayList 引用 上调用 add;使用参数 (int 3) 在 ArrayList 引用 上调用 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 引用 上调用 add 方法,参数为 (int 1);从 l 加载 → long 2;在 ArrayList 引用 上调用 add 方法,参数为 (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;在 ArrayList 引用 上调用 add 方法,参数为 (double 12.0);从 s 加载 → String "5";在 ArrayList 引用 上调用 add 方法,参数为 (String "5");隐式转换 ArrayList 引用List 引用List 引用;将 List 引用 存储到 list

列表访问edit

使用 列表访问运算符 '[]' 作为对 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 7 存储到 x

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

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

  • 使用 def 类型进行列表访问。

    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;将 def 存储到 d

    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 7 存储到 x

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

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

映射初始化edit

使用 映射初始化运算符 '[:]' 在堆上分配一个 Map 类型实例,并设置一组预定义的值。用于初始化 Map 类型实例的每一对值在插入到 Map 类型实例中时,使用 put 方法转换为 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 = [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

  • 使用非静态值进行映射初始化。

    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 0 存储到 b

    声明 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 加载 → 字节 0;从 i 加载 → 整数 1;在 HashMap 引用 上调用 put,参数为 (字节 0, 整数 1);从 l 加载 → 长整型 2;从 f 加载 → 浮点型 3.0;从 d 加载 → 双精度浮点型 4.0;提升 浮点型 3.0双精度浮点型 4.0:结果 双精度浮点型;隐式转换 浮点型 3.0双精度浮点型 3.0双精度浮点型 3.0;将 双精度浮点型 3.0双精度浮点型 4.0 相乘 → 双精度浮点型 12.0;在 HashMap 引用 上调用 put,参数为 (长整型 2, 双精度浮点型 12.0);从 d 加载 → 双精度浮点型 4.0;从 s 加载 → 字符串 "5";在 HashMap 引用 上调用 put,参数为 (双精度浮点型 4.0, 字符串 "5");隐式转换 HashMap 引用Map 引用Map 引用;将 Map 引用 存储到 map

Map 访问edit

使用 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,参数为 (字符串 'value2', 整数 2)

    map 加载 → Map 引用;在 Map 引用 上调用 put,参数为 (字符串 'value5', 整数 5)

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

    声明 String y;将 字符串 'value5' 存储到 y

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

  • 使用 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;将 def 存储到 d

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

    d 加载 → def;隐式转换 defHashMap 引用HashMap 引用;在 HashMap 引用 上调用 put,参数为 (字符串 'value5', 整数 5)

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

    声明 String y;将 字符串 'value5' 存储到 y

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

新建实例edit

使用 新建实例运算符 '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 引用;分配 HashMap 实例,参数为 (Map 引用) → HashMap 引用;隐式转换 HashMap 引用defdef;将 def 存储到 e

字符串连接edit

使用 字符串连接运算符 '+' 将两个值连接在一起,其中至少一个值为 字符串类型

语法

concatenate: expression '+' expression;

示例

  • 使用不同的原始类型进行字符串连接。

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

    声明 String x;将 字符串 "con" 存储到 x

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

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

  • 使用 def 类型进行字符串连接。

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

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

    字符串 "con"整数 2 连接 → 字符串 "con2";将 字符串 "con2"字符串 "cat" 连接 → 字符串 "con2cat" 隐式转换 字符串 "con2cat"defdef;将 def 存储到 d;(注意 d 的类型从 int 变为 String

Elvisedit

Elvis 由两个表达式组成。第一个表达式被评估以检查 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 中;