簡體   English   中英

傳遞無參數或null時的Java 3點參數(varargs)行為

[英]Java 3 dots parameter (varargs) behavior when passed no arguments or null

我試過這個並從JAVA得到奇怪的行為,有人可以幫我解釋一下嗎?

boolean testNull(String... string) {
    if(string == null) {
        return true;
    } else {
        System.out.println(string.getClass());
        return false;
    }
}

boolean callTestNull(String s) {
    return testNull(s);
}

然后我有測試用例:

    @Test
    public void test_cases() {
        assertTrue(instance.testNull(null)); // NULL
        assertFalse(instance.testNull()); // NOT NULL
        assertFalse(instance.callTestNull(null)); // NOT NULL
    }

現在的問題是,如果我叫testNull()直接與參數null ,我會得到true回來,但如果調用callTestNull()null ,這就要求testNull()它告訴我該參數不為空,但空數組。

問題是如果我直接使用參數null調用testNull(),我將返回true,但如果使用null調用callTestNull()調用testNull(),它會告訴我參數不是null,而是空數組。

是。 如果使用帶有編譯時類型 String的參數調用它,則編譯器知道它不能String[] ,因此它將其包裝在字符串數組中。 所以這:

String x = null;
testNull(x);

相當於:

String x = null;
testNull(new String[] { x });

此時,(誤導性命名的) string參數將具有非空值 - 相反,它將引用大小為1的數組,其唯一元素是空引用。

但是,當您在方法調用中直接使用null文本時,它可以直接轉換為String[] ,因此不執行包裝。

JLS第15.12.4.2節

如果被調用的方法是變量arity方法m,則它必須具有n> 0個形式參數。 對於某些T,m的最終形式參數必然具有類型T [],並且必須使用k≥0個實際參數表達式來調用m。

如果使用k≠n實際參數表達式調用m,或者,如果使用k = n實際參數表達式調用m並且第k個參數表達式的類型不與T []賦值兼容 ,則參數列表(e1,...,en-1,en,...,ek)被評估為好像被寫為(e1,...,en-1,new | T [] | {en,... ,ek}),其中| T [] | 表示T []的擦除(第4.6節)。

(強調我的。)

我強調的一點是,為什么只有當參數的編譯時類型是String而不是null類型時才會發生包裝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM