JE_03: Pomocí soukromého konstruktoru zajistěte nemožnost vytvoření instance

Občas budete potřebovat napsat třídu, která je jen seskupením statických metod a statických atributů. Takové třídy mají špatnou reputaci, protože někteří lidé je zneužívají k vytváření procedurálních programů v objektově orientovaných jazycích. Mají však i svá dobrá využití. Lze je použít k seskupení souvisejících metod s primitivními hodnotami nebo polí, podobně jako to činí java.lang.Math či java.util.Arrays, nebo k seskupení statických metod s objekty implementujícími určité rozhraní, jako to činí třída java.util.Collection. Lze je rovněž využít k seskupení metod ve finální třídě namísto rozšíření dané třídy.

Podobné pomocné třídy nebyly navrženy tak, aby se vytvářely jejich instance: taková instance by neměla žádný smysl. Chybějí-li však explicitní konstruktory, pak použije kompilátor veřejný, bezparametrický výchozí konstruktor. Uživatel nemůže odlišit takový konstruktor od jiných. Není neobvyklé, že se v publikovaných rozhraních API neúmyslně objevují třídy, jejichž instance lze vytvářet.

Pokusíte-li se zajistit nemožnost vytváření instance tím, že učiníte třídu abstraktní, nebude to fungovat. Lze vytvořit podtřídu dané třídy a následně také instanci této podtřídy. Navíc si může uživatel chybně myslet, že tato třída je určená k dědění (rada 15). Lze však jednoduše znemožnit vytváření instancí. Výchozí konstruktor se generuje, pouze pokud neobsahuje daná třída žádné explicitní konstruktory, takže nemožnost vytváření insatncí třídy zajistíte tak, že použijete jediný explicitní soukromý konstruktor:

// Pomocná třída, jejíž instanci nelze vytvořit
public class UtilityClass {

	// Potlačení výchozího konstruktoru, aby nebylo možné
	// vytvářet instance
	private UtilityClass() {
		// Tento konstruktor se nikdy nezavolá
	}

	. . .
}

Protože explicitní konstruktor je soukromý, není přístupný mimo danou třídu. Je tedy zaručeno, že se nikdy nevytvoří instance této třídy, pokud tedy nebude konstruktor volán uvnitř třídy samotné. Tento princip není příliš intuitivní, protože daný konstruktor je vytvořen právě proto, aby nemohl být volán. Je tedy vhodné doplnit komentář popisující smysl takového konstruktoru.

Vedlejším efektem je skutečnost, že toto uspořádání rovněž zabra�uje vytváření podtříd této třídy. všechny konstruktory musejí volat nějaký přístupný konstruktor nadtřídy, ať už explicitně nebo implicitně, a podtřída by neměla žádný přístupný konstruktor, který by mohla zavolat.