运算符:参考
编辑运算符:参考
编辑方法调用
编辑使用方法调用运算符 '()'
来调用引用类型值上的成员方法。根据方法调用期间每个参数的需要,隐式装箱/拆箱会被评估。当对目标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
隐式转换为def
→def
;将int 2
隐式转换为def
→def
;使用参数(int 1
,int 2
)调用Map
引用的put
方法声明
int z
;从m
加载 →Map
引用;使用参数(int 1
)调用Map
引用的get
方法 →def
;将def
隐式转换为int 2
→int 2
;将int 2
存储到z
声明
def d
;分配ArrayList
实例 →ArrayList
引用;将ArrayList
隐式转换为def
→def
;将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'
)调用Integer
的parseInt
方法 →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
隐式转换为def
→def
;将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
值的空安全。 -
带有
null
值的空安全;
列表初始化
编辑使用列表初始化运算符 '[]'
为堆分配一个List
类型实例,其中包含一组预定义的值。用于初始化List
类型实例的每个值在使用add
方法插入到List
类型实例时,都会转换为def
类型值。指定值的顺序将被保留。
语法
list_initialization: '[' expression (',' expression)* ']' | '[' ']';
示例
-
空
List
类型值的列表初始化。 -
使用静态值的列表初始化。
-
使用非静态值的列表初始化。
声明
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.0
和double 4.0
:结果double
;将float 3.0
隐式转换为double 3.0
→double 3.0
;将double 3.0
和double 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 2
→int 2
;从list
加载 →List
引用;使用参数 (int 1
) 调用List
引用上的get
方法 →def
;将def
隐式转换为int 5
→int 5
;将int 2
和int 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 5
→int 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
引用隐式转换为def
→def
;将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 2
→int 2
;从d
加载 →def
;将def
隐式转换为ArrayList
引用 →ArrayList
引用;使用参数 (int 1
) 调用ArrayList
引用上的get
方法 →def
;将def
隐式转换为int 5
→int 5
;将int 2
和int 5
相加 →int 7
;将int 7
存储到x
声明
int y
;将int 1
存储到y
声明
int z
;从d
加载 →ArrayList
引用;从y
加载 →def
;将def
隐式转换为int 1
→int 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 初始化。
-
使用非静态值的 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.0
和double 4.0
:结果为double
;隐式转换float 3.0
为double 3.0
→double 3.0
;double 3.0
和double 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
;隐式转换def
为int 2
→int 2
;从map
加载 →Map
引用;使用参数 (String 'value5'
) 调用Map
引用的get
方法 →def
;隐式转换def
为int 5
→int 5
;int 2
和int 5
相加 →int 7
;将int 7
存储到x
声明
String y
;将String 'value5'
存储到y
声明
int z
;从map
加载 →Map
引用;从y
加载 →String 'value5'
;使用参数 (String 'value5'
) 调用Map
引用的get
方法 →def
;隐式转换def
为int 5
→int 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
引用为def
→def
;将def
存储到d
从
d
加载 →def
;隐式转换def
为HashMap
引用 →HashMap
引用;使用参数 (String 'value2'
,int 2
) 调用HashMap
引用的put
方法从
d
加载 →def
;隐式转换def
为HashMap
引用 →HashMap
引用;使用参数 (String 'value5'
,int 5
) 调用HashMap
引用的put
方法声明
int x
;从d
加载 →def
;隐式转换def
为HashMap
引用 →HashMap
引用;使用参数 (String 'value2'
) 调用HashMap
引用的get
方法 →def
;隐式转换def
为int 2
→int 2
;从d
加载 →def
;使用参数 (String 'value5'
) 调用HashMap
引用的get
方法 →def
;隐式转换def
为int 5
→int 5
;int 2
和int 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)*)? ')';
示例
- 使用不同类型分配新的实例。
字符串连接
编辑使用 string
连接操作符 '+'
将两个值连接在一起,其中至少一个值为 String
类型。
语法
concatenate: expression '+' expression;
示例
-
使用不同的基本类型进行字符串连接。
-
使用
def
类型进行字符串连接。
Elvis 操作符
编辑Elvis 操作符由两个表达式组成。首先计算第一个表达式,检查其值是否为 null
。如果第一个表达式的值为 null
,则计算第二个表达式并使用其值。如果第一个表达式的值不为 null
,则使用第一个表达式的结果值。使用 Elvis
操作符 '?:'
作为条件操作符的快捷方式。
错误
- 如果第一个表达式或第二个表达式不能产生
null
值。
语法
elvis: expression '?:' expression;
示例
-
使用不同的引用类型进行 Elvis 操作。
声明
List x
;分配ArrayList
实例 →ArrayList
引用;隐式转换ArrayList
引用为List
引用 →List
引用;将List
引用存储到x
;声明
List y
;加载x
→List
引用;List
引用等于null
→false
;计算第一个表达式:List
引用 →List
引用;将List
引用存储到y
将
null
存储到y
;声明
List z
;加载y
→List 引用
;List 引用
等于null
→true
;评估第二个表达式:分配ArrayList
实例 →ArrayList 引用
;隐式转换ArrayList 引用
到List 引用
→List 引用
;将List 引用
存储到z
;