Měl jsem držet proměnné instance v Javě vždy inicializuje, nebo ne?

hlasů
5

Nedávno jsem začal nový projekt a já se snažím, aby mé proměnných instance vždy inicializovány na nějakou hodnotu, takže žádný z nich je kdykoliv null. Malý příklad níže:

public class ItemManager {

  ItemMaster itemMaster;
  List<ItemComponentManager> components;

  ItemManager() {
    itemMaster = new ItemMaster();
    components = new ArrayList<ItemComponentManager>();
  }

  ...
}

Jde o to především, aby se zabránilo zdlouhavé kontroly na nulu před použitím proměnnou instance někde v kódu. Zatím to funguje dobře a většinou nepotřebují null -hodnota, jak si můžete zkontrolovat také na prázdný řetězec nebo prázdný seznam, atd Nejsem s využitím tohoto přístupu k metodě rozsahem proměnné as jejich rozsah je velmi omezený, a tak neovlivňuje jiné části kódu.

To vše je tak trochu experimentální, tak bych chtěl vědět, jestli tento přístup může fungovat, nebo pokud existují nějaké úskalí, které jsem dosud vidí. Je to obvykle dobrý nápad, aby instance proměnné inicializovat?

Položena 13/02/2009 v 10:53
zdroj uživatelem
V jiných jazycích...                            


12 odpovědí

hlasů
9

I obvykle léčit prázdnou kolekci a kolekci null jako dvě oddělené věci:

Prázdný kolekce vyplývá, že vím, že jsou k dispozici nulové položky. Sbírka null mi řekne, že nevím stav sbírky, která je jiná věc.

Takže jsem opravdu si nemyslím, že je to buď / anebo. A já bych prohlásit proměnnou finále kdybych inicializovat v konstruktoru. Pokud jej prohlásit finále se stává pro čtenáře, že tato sbírka nemůže být null zcela jasné.

Odpovězeno 13/02/2009 v 11:00
zdroj uživatelem

hlasů
4

Za prvé a především, všechny non-konečné instanci proměnné musí být prohlášen za soukromé , pokud chcete udržet kontrolu!

Vezměme si líný konkretizaci stejně - i to se vyhne „špatný stav“, ale inicializuje pouze na použití:

class Foo {
    private List<X> stuff;
    public void add(X x) {
        if (stuff == null)
            stuff = new ArrayList<X>();
        stuff.add(x);
    }
    public List<X> getStuff() {
        if (stuff == null)
            return Collections.emptyList();
        return Collections.unmodifiableList(stuff);
    }
}

(Všimněte si použití Collections.unmodifiableList - pokud opravdu chcete, aby volající, aby bylo možné přidat / odebrat ze svého seznamu, měli byste dělat to neměnná)

Přemýšlet o tom, jak bude vytvořeno mnoho příkladů daného objektu. Pokud existuje mnoho, a vždy vytvořit seznamy (a mohli skončit s mnoha prázdných listů), mohli byste být vytvoření mnohem více objektů, než je potřeba.

Jiné, než to, že je to opravdu otázka vkusu a pokud můžete mít smysluplné hodnoty při postavit.

Pokud pracujete s DI / IOC, chcete rámec dělat práci za vás (i když byste mohli udělat to přes injekci konstruktoru; dávám přednost setters) - Scott

Odpovězeno 13/02/2009 v 13:52
zdroj uživatelem

hlasů
3

Řekl bych, že je naprosto v pořádku - jen tak dlouho, jak si vzpomenete, že máte „prázdné“ zástupné tam hodnoty a nikoli reálnými daty.

Jejich udržování null má tu výhodu, že nutí vás se s nimi vypořádat - jinak program zhroutí. Pokud vytvoříte prázdné objekty, ale na ně zapomenout dostanete nedefinované výsledky.

A jen proto, aby se vyjádřil k defencive kódování - Pokud jste ten, vytváření objektů a jejich nikdy nastavení null, není třeba zkontrolovat nulové pokaždé. Pokud z nějakého důvodu máte nulovou hodnotu, pak víte, že je někde něco katastrofálně špatně a program by měl selhat stejně.

Odpovězeno 13/02/2009 v 10:59
zdroj uživatelem

hlasů
2

Jak jsem řešit jakoukoli proměnnou Prohlašuji, je rozhodnout, zda se bude měnit v průběhu životnosti objektu (nebo třída pokud je statický). Je-li odpověď „ne“, pak jsem se, aby to finále.

Což je konečné vás nutí, aby jí hodnotu, když je vytvořen objekt ... Osobně bych udělat následující, pokud jsem věděl, že budu měnit, co bodu na adrese:

  private final ItemMaster itemMaster;
  soukromé finální komponenty List;

  // instance inicializace bloku - se děje v době výstavby
  {
      itemMaster = nový ItemMaster ();
      komponenty = new ArrayList ();
  }

Způsob, jakým je váš kód je právě teď je třeba zkontrolovat null po celou dobu, protože jste neoznačil proměnné jako soukromé (což znamená, že jakákoliv třída v jednom balení lze změnit hodnoty null).

Odpovězeno 13/02/2009 v 18:56
zdroj uživatelem

hlasů
2

Jsem narazil některých případech, kdy to způsobuje problémy. Během deserializace, některé rámce ne volat konstruktor, nevím, jak nebo proč se rozhodnout, jak to udělat, ale to se stává. To může mít za následek vaše hodnoty bytí null. Také jsem narazil na případ, kdy je konstruktér volal, ale z nějakého důvodu členské proměnné nejsou inicializovány.

Ve skutečnosti bych použít následující kód namísto ta vaše:

public class ItemManager {

  ItemMaster itemMaster = new ItemMaster();
  List<ItemComponentManager> components = new ArrayList<ItemComponentManager>();

  ItemManager() {
     ...
  }
  ...
}
Odpovězeno 13/02/2009 v 11:19
zdroj uživatelem

hlasů
2

Chtěl bych, aby byly v konečném znění , pokud je to možné. Pak musí být inicializována v konstruktoru a nemůže být null.

Měli byste také jejich soukromí v každém případě, aby se zabránilo další třídy od přiřazení null k nim. Pokud můžete zjistit, že null není nikdy přidělen ve své třídě pak tento přístup bude fungovat.

Odpovězeno 13/02/2009 v 11:09
zdroj uživatelem

hlasů
1

Objekt by měl být 100% připraven k použití po jeho postavena. Uživatelé by neměli být kontrola hodnoty Null. Defenzivní programování je způsob, jak jít - udržet kontrolu.

V zájmu suchý, můžete si dát kontroly v seřizovačů a prostě konstruktor volat jim. Tímto způsobem nemusíte kód kontroly dvakrát.

Odpovězeno 13/02/2009 v 11:45
zdroj uživatelem

hlasů
1

Jde o to především, aby se zabránilo zdlouhavý kontrolu NULL před použitím třídní proměnné někde v kódu.

Stále máte zkontrolovat null. knihoven třetích stran, a dokonce i API Java se někdy vrátí null.

Také konkretizaci objekt, který nesmí být nikdy použit, je nehospodárné, ale to bude záviset na návrhu vaší třídy.

Odpovězeno 13/02/2009 v 11:01
zdroj uživatelem

hlasů
1

Ano, je to velmi dobrý nápad, aby se inicializovat všechny proměnné třídy v konstruktoru.

Odpovězeno 13/02/2009 v 10:58
zdroj uživatelem

hlasů
0

Z názvu třídy „ItemManager“, ItemManager zní jako jedináček v některých aplikacích. Pokud ano, měli vyšetřovat a opravdu, ale opravdu, víte závislost injekce. Použít něco jako Spring ( http://www.springsource.org/ ) vytvořte a aplikujte seznam ItemComponentManagers do ItemManager.

Bez DI, inicializace ručně závažných aplikacích je noční můra pro ladění a připojování do různých „manažer“ tříd, aby úzké zkoušky je peklo.

Použití DI vždy (i při konstrukci testů). U datových objektů, vytvořit metodu get (), která vytvoří seznam, pokud neexistuje. Nicméně v případě, že objekt je složité, téměř jistě najde svůj život lepší pomocí Factory nebo Builder a mají F / B nastavit proměnné členů podle potřeby.

Odpovězeno 13/02/2009 v 20:23
zdroj uživatelem

hlasů
0

Pokud je to všechno kód a chcete nastavit tuto úmluvu, by mělo být pěkná věc mít. Souhlasím s Paulovy komentáře však, že nic nebrání tomu nějaký potulný kód z náhodně nastavit jeden ze svých tříd proměnných NULL. Jako obecné pravidlo, vždycky jsem zkontrolovat null. Jo, je to PITA, ale obranný kódování může být dobrá věc.

Odpovězeno 13/02/2009 v 10:59
zdroj uživatelem

hlasů
0

Co se stane, když se v jednom ze svých metod nastavení

itemMaster = null; 

nebo vrátit odkaz na ItemManager nějaké jiné třídě a nastaví itemMaster jako null. (Můžete chránit proti tomuto snadno vrátit klon vaše ItemManager etc)

Chci udržet kontrolu jak je to možné.

Odpovězeno 13/02/2009 v 10:56
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more