[英]Java Pattern Variable Scope
我正在通過 Oracle 的官方文檔來了解 Java 17 中的模式變量 scope 。在以下示例中,方法testScope1
的工作原理如文檔中所述,但方法testScope2
給出了編譯錯誤。 我無法弄清楚為什么方法的void
返回類型會導致問題?
interface Vehicle{}
class Car implements Vehicle{}
class Pattern{
public int testScope1(Vehicle v){
if(!(v instanceof Car c)){
return 1;
}
System.out.println(c.toString()); //WORKS FINE
return 2;
}
public void testScope2(Vehicle v){
if(!(v instanceof Car c)){
}
System.out.println(c.toString()); //COMPILE TIME ERROR: Cannot resolve symbol c
}
}
放一個 else 語句。 只有在instanceof
運算符產生true
時才會創建模式變量。 否則沒有變量,因此編譯器錯誤。
public void testScope2(Vehicle v){
if(!(v instanceof Car c)){
} else {
System.out.println(c.toString());
}
}
編輯: testScope1
方法不需要else
語句,因為return
語句已經存在。 如果v
不是Car
的實例, return
語句確保控制永遠不會到達c.toString()
。
想想如果v
不是Car
實例會發生什么:
testScope1
中, return 1;
語句導致方法退出。 不執行該方法的后續語句。 一切都很好。testScope2
中沒有return
,所以控制流到達c.toString()
。 但是v
不是Car
,所以……什么是c
?,它不能存在,因為它必須是Car
類型,但這是反事實的。 這就是您收到錯誤“無法解析符號c
”的原因。對此花了更多的思考后,我有一個解釋:只有在該代碼段的 instanceof 明確為真時,才能訪問該變量。
在 testScope1 中,您無法在 if 語句中訪問c
。 但是由於 if 語句之后的代碼只有在 instanceof 為真時才會執行, c
是可以訪問的。
在 testScope1 中,您無法在 if 語句中訪問c
。 但是由於 if 語句之后的代碼被執行,無論 instanceof 是真還是假c
都無法訪問。 畢竟我們可能會遇到錯誤的情況,編譯器會相應地采取行動。
模式變量(模式中聲明的綁定變量)使用流敏感范圍。 與在 scope 中用於連續區域的普通本地變量不同,模式變量在 scope中,它們將由它們的聲明模式明確分配。
如果你有一個if
語句:
if (x instanceof Foo(var v)) {
A;
}
else {
B;
}
那么v
在 scope 中是A
,但不是B
,因為我們不能保證在到達B
的情況下v
一定會被賦值。 如果我們使用明顯的重構來反轉我們的測試:
if (!(x instanceof Foo(var v))) {
B;
}
else {
A;
}
也是如此; v
在 scope 中A
但不在B
中。 規則與本地人的明確分配規則完全相同——“如果我達到這一點,這個值是否保證已經被分配了一個值。”
其他條件構造,例如短路&&
和||
,也參與此范圍界定。 例如,以下是有效的:
if (x instanceof Foo(var v) && v != null) {
A;
}
但以下不是:
if (x instanceof Foo(var v) || v != null) {
A;
}
因為在后者中,當我們到達v != null
子句時,不能保證v
已經被賦值。
這些規則甚至包含非本地控制流,例如異常。 例如,如果我們有:
if (!(x instanceof Foo(var v)) {
System.out.println("Not a Foo");
}
B(v);
這將是一個錯誤,因為當我們到達B(v)
時,不能保證v
已經被賦值,但是如果if
塊突然完成:
if (!(x instanceof Foo(var v)) {
throw new NotFooException();
}
B(v);
那么v
在B(v)
處的 scope 中,因為我們保證如果我們到達那個點, v
已經被分配了一個值。
這可能看起來很復雜,但實際上非常簡單:考慮到您對if
、 throw
等結構的流控制的了解,模式變量是否保證在給定點被賦值? 如果是這樣,那么它在 scope 中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.