Díky za veškeré konzultace.

Jinak ano, Joshua Blosh je skvělý. Kdysi dávno jsem si koupil první edici
vydanou Gradou, ale už pár let co jsem neprogramoval se na ní jenom práší
:-) Tohle je typ knihy do které se vyplatí investovat a i si ji třeba z
Amazonu objednat.

Libor

2011/4/5 Ladislav Thon <[email protected]>

> Předně, tohle může být někdy chtěné (i když teoretici OOP by vám za to
> urvali hlavu). Pokud ne, getter by měl vracet kopii (někdy se říká
> „defenzivní kopii “), ne přímo tu členskou proměnnou.
>
> Konkrétně u Date se dokonce někdy dělá i to, že uvnitř objektu se uchovává
> jen long hodnota date.getTime(), každopádně getter vypadá
>
> Date getNarozeni() {
>   return new Date(narozeni.getTime());
> }
>
> Pokud se dobře pamatuju, dobře je to popsáno v Effective Java (doporučuju
> druhé vydání, byť myslím není dostupné v češtině).
>
> LT
> Dne 5.4.2011 8:47 "Libor Jelinek" <[email protected]> napsal(a):
>
> > 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
> >>
>

Odpovedet emailem