JE_27 - Vracejte pole nulové délky a nikoli hodnoty null

Není neobvyklé setkat se s metodami, které vypadají podobně:

private List cheesesInStock = . . .;


/**
 * @return pole obsahující všechny sýry v obchodě
 *         nebo null, pokud nelze zakoupit žádné sýry.
 */

public Cheese[] getCheeses() {
	if (cheesesInStock.size() == 0)
		return null;
	. . .
}

Není žádný důvod vytvářet speciální případ pro situaci, kdy nelze zakoupit žádné sýry. Pokud tak učiníte, musí klient používat dodatečný kód zpracovávající návratovou hodnotu null, například:

Cheese[] cheeses = shop.getCheeses();
if (cheeses != null && Arrays.asList(shop.getCheeses()).contains(Cheese.STILTON))
	System.out.println("Dost dobrý, prostě něco.");

namísto:

if (Arrays.asList(shop.getCheeses()).contains(Cheese.STILTON))
	System.out.println("Dost dobrý, prostě něco.");

Podobný kód je zapotřebí v téměř každém použití metody, která vrací null namísto pole nulové délky. Je náchylný k chybám, protože proramátor píšící klienta může zapomenout vytvoři kód pro speciální případ zpracování hodnoty null. Taková chyba může zůstat bez povšimnutí roky, protože podobné metody obvykle vracejí jeden nebo více objektů. Za zmínku ještě stojí ne již tak zásadní skutečnost, že vracení null namísto pole nulové délky také komplikuje samotnou metodu vracení pole.

Občas se můžete setkat s argumentem, že vracení hodnoty null je lepší než vracení pole nulové délky, protože šetří náklady na alokování takového pole. Tento argument není správný ze dvou hledisek. Zaprvé, není vhodné zabývat se výkonností na takovéto úrovni, pokud profilování neukázalo, že daná metoda skutečně přispívá k problémům s výkonností (rada 37). Za druhé, je možné vracet stejné pole nulové délky z každého volání nevracejícího žádné položky, protože pole nulové déky jsou neměnitelná a neměnitelné objekty lze volně sdílet (rada 13). Přesně k tomu dochází, když používáte standardní idiom převádění položek z kolekce do typového pole:

private List cheesesInStock = . . .;
private final static Cheese[] NULL_CHEESE_ARRAY = new Cheese[0];


/**
 * @return pole obsahující všechny sýry v obchodě
 */


public Cheese[] getCheeses() {
	return (Cheese[]) cheesesInStock.toArray(NULL_CHEESE_ARRAY);
}

V tomto idiomu se metodě toArray předává konstanta pole nulové délky indikující požadovaný návratový typ. Metoda toArray obvykle alokuje vrácené pole, je-li však daná kolekce prázdná, použije vstupní pole a specifikace Collection.toArray(Object[]) zaručuje, že dojde k vrácení vstupního pole, pokud je dostatečně velké, a dokáže obsaáhnout danou kolekci. Pro tento idiom nikdy nealokuje pole nulové délky, ale místo toho opeakovaně používá "konstantu specifikátoru typu".

Celkově lze říci, že neexistuje důvod k vracení null z metody pracující s polem namísto vrácení pole nulové délky. Tento idiom je pravděpodobně přežitkem z programovacího jazyka C, v němž se délky polí vracejí odděleně od vlastních polí. V jazyce C není výhodné alokovat pole, pokud je jako délka vrácena nula.