運算子
關係運算子
關係運算子(等於、不等於、小於、小於等於、大於、大於等於)透過標準運算子表示法支援。這些運算子適用於 Number 型別以及實現 Comparable 的型別。以下列表顯示了關係運算子的一些示例
-
Java
-
Kotlin
// evaluates to true
boolean trueValue = parser.parseExpression("2 == 2").getValue(Boolean.class);
// evaluates to false
boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class);
// evaluates to true
boolean trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean.class);
// uses CustomValue:::compareTo
boolean trueValue = parser.parseExpression("new CustomValue(1) < new CustomValue(2)").getValue(Boolean.class);
// evaluates to true
val trueValue = parser.parseExpression("2 == 2").getValue(Boolean::class.java)
// evaluates to false
val falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean::class.java)
// evaluates to true
val trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean::class.java)
// uses CustomValue:::compareTo
val trueValue = parser.parseExpression("new CustomValue(1) < new CustomValue(2)").getValue(Boolean::class.java);
|
大於和小於與 如果你更喜歡數值比較,請避免基於數字的 |
每個符號運算子也可以用純文字等價物來指定。這避免了符號對錶達式嵌入的文件型別(例如 XML 文件)具有特殊含義的問題。文字等價物如下
-
lt(<) -
gt(>) -
le(<=) -
ge(>=) -
eq(==) -
ne(!=)
所有文字運算子都對大小寫不敏感。
除了標準關係運算子之外,SpEL 還支援 between、instanceof 和基於正則表示式的 matches 運算子。以下列表顯示了所有三個運算子的示例
-
Java
-
Kotlin
boolean result;
// evaluates to true
result = parser.parseExpression(
"1 between {1, 5}").getValue(Boolean.class);
// evaluates to false
result = parser.parseExpression(
"1 between {10, 15}").getValue(Boolean.class);
// evaluates to true
result = parser.parseExpression(
"'elephant' between {'aardvark', 'zebra'}").getValue(Boolean.class);
// evaluates to false
result = parser.parseExpression(
"'elephant' between {'aardvark', 'cobra'}").getValue(Boolean.class);
// evaluates to true
result = parser.parseExpression(
"123 instanceof T(Integer)").getValue(Boolean.class);
// evaluates to false
result = parser.parseExpression(
"'xyz' instanceof T(Integer)").getValue(Boolean.class);
// evaluates to true
result = parser.parseExpression(
"'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
// evaluates to false
result = parser.parseExpression(
"'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
// evaluates to true
var result = parser.parseExpression(
"1 between {1, 5}").getValue(Boolean::class.java)
// evaluates to false
result = parser.parseExpression(
"1 between {10, 15}").getValue(Boolean::class.java)
// evaluates to true
result = parser.parseExpression(
"'elephant' between {'aardvark', 'zebra'}").getValue(Boolean::class.java)
// evaluates to false
result = parser.parseExpression(
"'elephant' between {'aardvark', 'cobra'}").getValue(Boolean::class.java)
// evaluates to true
result = parser.parseExpression(
"123 instanceof T(Integer)").getValue(Boolean::class.java)
// evaluates to false
result = parser.parseExpression(
"'xyz' instanceof T(Integer)").getValue(Boolean::class.java)
// evaluates to true
result = parser.parseExpression(
"'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean::class.java)
// evaluates to false
result = parser.parseExpression(
"'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean::class.java)
|
因此, |
請注意基本型別,因為它們會立即被裝箱成它們的包裝型別。例如,1 instanceof T(int) 評估為 false,而 1 instanceof T(Integer) 評估為 true。 |
邏輯運算子
SpEL 支援以下邏輯 (boolean) 運算子
-
and(&&) -
or(||) -
not(!)
所有文字運算子都對大小寫不敏感。
以下示例展示瞭如何使用邏輯運算子
-
Java
-
Kotlin
// -- AND --
// evaluates to false
boolean falseValue = parser.parseExpression("true and false").getValue(Boolean.class);
// evaluates to true
String expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')";
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
// -- OR --
// evaluates to true
boolean trueValue = parser.parseExpression("true or false").getValue(Boolean.class);
// evaluates to true
String expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')";
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
// -- NOT --
// evaluates to false
boolean falseValue = parser.parseExpression("!true").getValue(Boolean.class);
// -- AND and NOT --
String expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')";
boolean falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
// -- AND --
// evaluates to false
val falseValue = parser.parseExpression("true and false").getValue(Boolean::class.java)
// evaluates to true
val expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')"
val trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java)
// -- OR --
// evaluates to true
val trueValue = parser.parseExpression("true or false").getValue(Boolean::class.java)
// evaluates to true
val expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')"
val trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java)
// -- NOT --
// evaluates to false
val falseValue = parser.parseExpression("!true").getValue(Boolean::class.java)
// -- AND and NOT --
val expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')"
val falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java)
字串運算子
你可以在字串上使用以下運算子。
-
連線 (
+) -
減法 (
-)-
用於包含單個字元的字串
-
-
重複 (
*)
以下示例展示了字串運算子的用法
-
Java
-
Kotlin
// -- Concatenation --
// evaluates to "hello world"
String helloWorld = parser.parseExpression("'hello' + ' ' + 'world'")
.getValue(String.class);
// -- Character Subtraction --
// evaluates to 'a'
char ch = parser.parseExpression("'d' - 3")
.getValue(char.class);
// -- Repeat --
// evaluates to "abcabc"
String repeated = parser.parseExpression("'abc' * 2")
.getValue(String.class);
// -- Concatenation --
// evaluates to "hello world"
val helloWorld = parser.parseExpression("'hello' + ' ' + 'world'")
.getValue(String::class.java)
// -- Character Subtraction --
// evaluates to 'a'
val ch = parser.parseExpression("'d' - 3")
.getValue(Character::class.java);
// -- Repeat --
// evaluates to "abcabc"
val repeated = parser.parseExpression("'abc' * 2")
.getValue(String::class.java);
數學運算子
你可以在數字上使用以下運算子,並且強制執行標準運算子優先順序。
-
加法 (
+) -
減法 (
-) -
遞增 (
++) -
遞減 (
--) -
乘法 (
*) -
除法 (
/) -
模數 (
%) -
指數冪 (
^)
除法和模數運算子也可以用純文字等價物來指定。這避免了符號對錶達式嵌入的文件型別(例如 XML 文件)具有特殊含義的問題。文字等價物如下
-
div(/) -
mod(%)
所有文字運算子都對大小寫不敏感。
|
遞增和遞減運算子可以與可寫入的變數或屬性一起使用字首 ( |
以下示例展示了數學運算子的用法
-
Java
-
Kotlin
Inventor inventor = new Inventor();
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
// -- Addition --
int two = parser.parseExpression("1 + 1").getValue(int.class); // 2
// -- Subtraction --
int four = parser.parseExpression("1 - -3").getValue(int.class); // 4
double d = parser.parseExpression("1000.00 - 1e4").getValue(double.class); // -9000
// -- Increment --
// The counter property in Inventor has an initial value of 0.
// evaluates to 2; counter is now 1
two = parser.parseExpression("counter++ + 2").getValue(context, inventor, int.class);
// evaluates to 5; counter is now 2
int five = parser.parseExpression("3 + ++counter").getValue(context, inventor, int.class);
// -- Decrement --
// The counter property in Inventor has a value of 2.
// evaluates to 6; counter is now 1
int six = parser.parseExpression("counter-- + 4").getValue(context, inventor, int.class);
// evaluates to 5; counter is now 0
five = parser.parseExpression("5 + --counter").getValue(context, inventor, int.class);
// -- Multiplication --
six = parser.parseExpression("-2 * -3").getValue(int.class); // 6
double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(double.class); // 24.0
// -- Division --
int minusTwo = parser.parseExpression("6 / -3").getValue(int.class); // -2
double one = parser.parseExpression("8.0 / 4e0 / 2").getValue(double.class); // 1.0
// -- Modulus --
int three = parser.parseExpression("7 % 4").getValue(int.class); // 3
int oneInt = parser.parseExpression("8 / 5 % 2").getValue(int.class); // 1
// -- Exponential power --
int maxInt = parser.parseExpression("(2^31) - 1").getValue(int.class); // Integer.MAX_VALUE
int minInt = parser.parseExpression("-2^31").getValue(int.class); // Integer.MIN_VALUE
// -- Operator precedence --
int minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(int.class); // -21
val inventor = Inventor()
val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
// -- Addition --
var two = parser.parseExpression("1 + 1").getValue(Int::class.java) // 2
// -- Subtraction --
val four = parser.parseExpression("1 - -3").getValue(Int::class.java) // 4
val d = parser.parseExpression("1000.00 - 1e4").getValue(Double::class.java) // -9000
// -- Increment --
// The counter property in Inventor has an initial value of 0.
// evaluates to 2; counter is now 1
two = parser.parseExpression("counter++ + 2").getValue(context, inventor, Int::class.java)
// evaluates to 5; counter is now 2
var five = parser.parseExpression("3 + ++counter").getValue(context, inventor, Int::class.java)
// -- Decrement --
// The counter property in Inventor has a value of 2.
// evaluates to 6; counter is now 1
var six = parser.parseExpression("counter-- + 4").getValue(context, inventor, Int::class.java)
// evaluates to 5; counter is now 0
five = parser.parseExpression("5 + --counter").getValue(context, inventor, Int::class.java)
// -- Multiplication --
six = parser.parseExpression("-2 * -3").getValue(Int::class.java) // 6
val twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double::class.java) // 24.0
// -- Division --
val minusTwo = parser.parseExpression("6 / -3").getValue(Int::class.java) // -2
val one = parser.parseExpression("8.0 / 4e0 / 2").getValue(Double::class.java) // 1.0
// -- Modulus --
val three = parser.parseExpression("7 % 4").getValue(Int::class.java) // 3
val oneInt = parser.parseExpression("8 / 5 % 2").getValue(Int::class.java) // 1
// -- Exponential power --
val maxInt = parser.parseExpression("(2^31) - 1").getValue(Int::class.java) // Integer.MAX_VALUE
val minInt = parser.parseExpression("-2^31").getValue(Int::class.java) // Integer.MIN_VALUE
// -- Operator precedence --
val minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Int::class.java) // -21
賦值運算子
要設定屬性,請使用賦值運算子 (=)。這通常在呼叫 setValue 時完成,但也可以在呼叫 getValue 時完成。以下列表展示了兩種使用賦值運算子的方式
-
Java
-
Kotlin
Inventor inventor = new Inventor();
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
parser.parseExpression("name").setValue(context, inventor, "Aleksandar Seovic");
// alternatively
String aleks = parser.parseExpression(
"name = 'Aleksandar Seovic'").getValue(context, inventor, String.class);
val inventor = Inventor()
val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
parser.parseExpression("name").setValue(context, inventor, "Aleksandar Seovic")
// alternatively
val aleks = parser.parseExpression(
"name = 'Aleksandar Seovic'").getValue(context, inventor, String::class.java)
過載運算子
預設情況下,SpEL 的 Operation 列舉中定義的數學運算(ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS 和 POWER)支援數字等簡單型別。透過提供 OperatorOverloader 的實現,表示式語言可以支援這些操作在其他型別上。
例如,如果我們要過載 ADD 運算子以允許使用 + 符號連線兩個列表,我們可以實現一個自定義的 OperatorOverloader 如下。
pubic class ListConcatenation implements OperatorOverloader {
@Override
public boolean overridesOperation(Operation operation, Object left, Object right) {
return (operation == Operation.ADD &&
left instanceof List && right instanceof List);
}
@Override
public Object operate(Operation operation, Object left, Object right) {
if (operation == Operation.ADD &&
left instanceof List list1 && right instanceof List list2) {
List result = new ArrayList(list1);
result.addAll(list2);
return result;
}
throw new UnsupportedOperationException(
"No overload for operation %s and operands [%s] and [%s]"
.formatted(operation, left, right));
}
}
如果我們將 ListConcatenation 註冊為 StandardEvaluationContext 中的 OperatorOverloader,我們就可以評估像 {1, 2, 3} + {4, 5} 這樣的表示式,如下例所示。
-
Java
-
Kotlin
StandardEvaluationContext context = new StandardEvaluationContext();
context.setOperatorOverloader(new ListConcatenation());
// evaluates to a new list: [1, 2, 3, 4, 5]
parser.parseExpression("{1, 2, 3} + {2 + 2, 5}").getValue(context, List.class);
StandardEvaluationContext context = StandardEvaluationContext()
context.setOperatorOverloader(ListConcatenation())
// evaluates to a new list: [1, 2, 3, 4, 5]
parser.parseExpression("{1, 2, 3} + {2 + 2, 5}").getValue(context, List::class.java)
|
|
|
任何使用過載運算子的表示式都無法編譯。有關詳細資訊,請參閱 編譯器限制。 |