Jak v Javě ukazatele nejsou, ale vlastně tak trochu jsou, je podle mě ve výsledku ještě komplikovanější, než kdyby opravdu byly :-)
Může se Vás zeptat na bug, který zmiňujete ( http://findbugs.sourceforge.net/bugDescriptions.html#EI_EXPOSE_REP)? Jak přesně se proti tomu bránit? Tento prográmek by mi asi Findbugs označil právě chybou EI_EXPOSE_REP, protože mi opravdu umoňuje vynulovat datum narození zaměstnance i když jsem si ho označil jako private a nezveřejňuji setter. import java.util.Date; public class ZmenaBezSetteru { public static void main(String[] args) { Zamestnanec zam = new Zamestnanec(new Date(System.currentTimeMillis())); System.out.println("Osoba2.getNarozeni() = " + zam.getNarozeni()); zam.getNarozeni().setTime(0L); System.out.println("Osoba2.getNarozeni() = " + zam.getNarozeni()); } } class Zamestnanec { private Date narozeni; Zamestnanec(Date narozeni) { this.narozeni = narozeni; } public Date getNarozeni() { /*Zamestnanec kopieZamestnance = new Zamestnanec(narozeni); return kopieZamestnance.getNarozeni();*/ return narozeni; } } Ovšem do jaké podoby přepsat Zamestnanec.getNarozeni(), aby teda nevracela referenci na privátní objekt Date, ale kopii. Tedy odolné proti zam.getNarozeni().setTime(0L);, aby i po tomto příkazu zůstalo datum narození v nezměné? První co mě napadá je přepsat getNarozeni() na toto: public Date getNarozeni() { Zamestnanec kopieZamestnance = new Zamestnanec(narozeni); return kopieZamestnance.getNarozeni(); } Ovšem s tím nepochodím a skončím s ošklivou chybou: Exception in thread "main" java.lang.StackOverflowError at Zamestnanec.<init>(ZmenaBezSetteru.java:16) at Zamestnanec.getNarozeni(ZmenaBezSetteru.java:21) (a tento řádek vypsán ještě asi 30x :-)) Proč skončí tato varianta s vytvořením nového objektu na sebe sama s chybou StackOverflowError? Když zkusím druhé co mě napadá na toto: public Date getNarozeni() { return (Date) narozeni.clone(); } Pak již hlavní program vypíše 2x po sobě stejné datum. -- Libor 2011/4/4 Ondřej Fafejta <[email protected]> > 2011/4/4 Robert Novotny <[email protected]>: > > Este by som to vylepsil, aby bolo vidiet efekt: > > > > I. Primitivy hodnotou: > > > > public static void zlyPokusOZmenuParametra(int i) { > > ++i; > > } > > > > int i = 1; > > zlyPokusOZmenuParametra(i); > > System.out.println("i == " + i); // 1 > > > > II. Objekty referenciou > > > > public static void zmenDate(Date d) { > > d.setTime(0L); > > } > > > > Date date = new Date(); > > System.out.println("date == " + date); // v case mojeho spusteni > > ... date == Mon Apr 04 14:15:27 CEST 2011 > > zmenDate(date); > > System.out.println("date == " + date); // date == Thu Jan 01 > > 01:00:00 CET 1970 > > > jj. tento příklad je výstižnější ... (návratový typ je zbytečně matoucí > ;-)) > > Jinak ještě doplním, že findbugs hlásí chybu, když např. entita má > getter pro parametr, u kterého můžeme přepsat hodnotu bez toho abychom > volali setter... > > http://findbugs.sourceforge.net/bugDescriptions.html#EI_EXPOSE_REP > > např. (píšu z hlavy - určitě někde budu mít překlep ;)) > > public class NejakaEntita implements Serializable { > private Date createdAt; > > public Date getCreatedAt() { > return createdAt; > } > } > > Fafi >
