运算符:参考

编辑

方法调用

编辑

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

    声明int z;从m加载 → Map引用;使用参数(int 1)调用Map引用的get方法 → def;将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引用的get方法 → def;将def隐式转换为Integer 1引用 → Integer 1引用;调用Integer 1引用的toString方法 → String '1';使用参数(String '1')调用IntegerparseInt方法 → int 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引用@1的x加载 → int 1;将int 1隐式转换为defdef;将def存储到Example引用@0的y;(注意Example引用@0和Example引用@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引用@1的z加载 → List引用;使用参数(int 0)调用List引用的get方法 → int 1;将int 1存储到List引用@0的x;(注意Example引用@0和Example引用@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引用的factory方法 → List引用;将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;使用参数 (int 1) 调用 ArrayList 引用上的 add 方法;从 l 加载 → long 2;使用参数 (long 2) 调用 ArrayList 引用上的 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;使用参数 (double 12.0) 调用 ArrayList 引用上的 add 方法;从 s 加载 → String "5";使用参数 (String "5") 调用 ArrayList 引用上的 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 引用;使用参数 (int 1) 调用 List 引用上的 add 方法

    list 加载 → List 引用;使用参数 (int 2) 调用 List 引用上的 add 方法

    list 加载 → List 引用;使用参数 (int 3) 调用 List 引用上的 add 方法

    list 加载 → List 引用;使用参数 (int 0, int 2) 调用 List 引用上的 set 方法

    list 加载 → List 引用;使用参数 (int 1, int 5) 调用 List 引用上的 set 方法

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

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

    声明 int z;从 list 加载 → List 引用;从 y 加载 → int 1;使用参数 (int 1) 调用 List 引用上的 get 方法 → def;将 def 隐式转换为 int 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;将 def 隐式转换为 ArrayList 引用 → ArrayList 引用;使用参数 (int 1) 调用 ArrayList 引用上的 add 方法

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

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

    d 加载 → def;将 def 隐式转换为 ArrayList 引用 → ArrayList 引用;使用参数 (int 0, int 2) 调用 ArrayList 引用上的 set 方法

    d 加载 → def;将 def 隐式转换为 ArrayList 引用 → ArrayList 引用;使用参数 (int 1, int 5) 调用 ArrayList 引用上的 set 方法

    声明 def x;从 d 加载 → def;将 def 隐式转换为 ArrayList 引用 → ArrayList 引用;使用参数 (int 0) 调用 ArrayList 引用上的 get 方法 → def;将 def 隐式转换为 int 2int 2;从 d 加载 → def;将 def 隐式转换为 ArrayList 引用 → ArrayList 引用;使用参数 (int 1) 调用 ArrayList 引用上的 get 方法 → def;将 def 隐式转换为 int 5int 5;将 int 2int 5 相加 → int 7;将 int 7 存储到 x

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

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

Map 初始化

编辑

使用 Map 初始化操作符 '[:]' 来分配一个 Map 类型实例到堆中,并设置一组预定义的值。用于初始化 Map 类型实例的每一对值在使用 put 方法插入到 Map 类型实例时都被转换为 def 类型的值。

语法

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

示例

  • Map 类型值的 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 引用;使用参数 (int 1, int 2) 调用 HashMap 引用上的 put 方法;使用参数 (int 3, int 4) 调用 HashMap 引用上的 put 方法;使用参数 (int 5, int 6) 调用 HashMap 引用上的 put 方法;将 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 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 加载 → byte 0;从 i 加载 → int 1;使用参数 (byte 0, int 1) 调用 HashMap 引用的 put 方法;从 l 加载 → long 2;从 f 加载 → float 3.0;从 d 加载 → double 4.0;提升 float 3.0double 4.0:结果为 double;隐式转换 float 3.0double 3.0double 3.0double 3.0double 4.0 相乘 → double 12.0;使用参数 (long 2, double 12.0) 调用 HashMap 引用的 put 方法;从 d 加载 → double 4.0;从 s 加载 → String "5";使用参数 (double 4.0, String "5") 调用 HashMap 引用的 put 方法;隐式转换 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 引用;使用参数 (String 'value2', int 2) 调用 Map 引用的 put 方法

    map 加载 → Map 引用;使用参数 (String 'value5', int 5) 调用 Map 引用的 put 方法

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

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

    声明 int z;从 map 加载 → Map 引用;从 y 加载 → String 'value5';使用参数 (String 'value5') 调用 Map 引用的 get 方法 → def;隐式转换 defint 5int 5;将 int 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 引用;使用参数 (String 'value2', int 2) 调用 HashMap 引用的 put 方法

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

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

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

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

新建实例

编辑

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

重载的构造函数是指与两个或多个构造函数共享相同名称的构造函数。只要参数的数量不同,就可以根据参数个数(arity)重载构造函数,即对多个构造函数使用相同的引用类型名称。

错误

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

语法

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 连接操作符 '+' 将两个值连接在一起,其中至少一个值为 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 zint 4int 5 相加 → int 9int 9String "9concat" 连接;将 String "9concat" 存储到 z;(注意,由于特定运算的优先级和结合性,加法在连接之前执行)

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

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

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

    String "con"int 2 连接 → String "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