[ anon315 @ 05.06.2007. 19:55 ] @
Mozda previse mastam, ali me ipak zanima da li postoji nacin da se u telu metode dobije referenca na objekat koji je pozvao metodu, bez da se eksplicitno predaje this, kao argument metode? |
[ anon315 @ 05.06.2007. 19:55 ] @
[ nemnesic @ 05.06.2007. 20:53 ] @
ne verujem da mozes, ali...negde sam cuo / procitao da sta ako bacis
exception i posle uhvatis caller name? Throwable.getStackTrace() i nekako to parsujes i nadjes ko te je zvao.... my 2c [ anon315 @ 05.06.2007. 21:19 ] @
Hehe, ali ne treba mi samo info ko me je zvao, vec da nesto radim sa njim :)
[ nemnesic @ 05.06.2007. 21:24 ] @
hmmm...
jel mozes tu da iskoristis arch4j? znaci nadjes ko te je zvao...a pre toga napravis template sa arch4j...i onda samo zammenis ime...hmmm...mozda ja mastam..:) [ X Files @ 05.06.2007. 21:28 ] @
Poz,
nemnesic, jesi li videp PP koju sam ti poslao? [ anon315 @ 05.06.2007. 21:37 ] @
Citat: nemnesic: hmmm... jel mozes tu da iskoristis arch4j? znaci nadjes ko te je zvao...a pre toga napravis template sa arch4j...i onda samo zammenis ime...hmmm...mozda ja mastam..:) Hm, nisam cuo za to, pogledacu... [ uranium @ 06.06.2007. 05:03 ] @
Da li bi neko bio ljubazan da objasni o čemu se ovde radi?
Ako imamo neki metod f(), on mora biti metod neke klase recimo A. I sad ako je x instanca neke klase B (podklasa klase A) prilikom poziva x.f() unutar tela metode f() će važiti this == x i sa this možemo da radimo šta nam je volja... Jasno je da this nije eksplicitno prosleđen... Am I missing something here? ![]() [Ovu poruku je menjao uranium dana 06.06.2007. u 06:33 GMT+1] [ anon315 @ 06.06.2007. 08:35 ] @
Niko nije rekao da je B podklasa A, sta god ti to znacilo..
Code: public class A { // ... public void someMethodOfA() { B b = new B(); b.someMethodOfB(); } public void someOtherMethodOfA() { // do something } } public class B { // ... public void someMethodOfB() { // nema argumenta tipa A // Ovde hocu da pozovem someOtherMethodOfA od instance klase A koja je pozvala ovu metodu someMethodOfB } } Nadam se da ti je sada jasnije.. [ Java Beograd @ 06.06.2007. 08:38 ] @
@Uranium Tvoj post nema veze sa osnovnim pitanjem u temi.
@Vanja Jel ti je tema više kao "intelekualna rasprava" ili imaš konkretan problem ? [ anon315 @ 06.06.2007. 09:18 ] @
Intelektualna
![]() [ Black @ 06.06.2007. 13:24 ] @
[ anon315 @ 06.06.2007. 13:35 ] @
Ma ne bi verovao koliko ;)
Salu na stranu, naleteo sam u jednom programu na gomilu predavanje this-a metodama upravo iz pomenutog razloga, pa mi se rodilo pitanje.. [ Java Beograd @ 07.06.2007. 09:15 ] @
Nisam o tome nikad razmišljao. Ili predam this, ili ako to ima smisla napravim od nečega singleton ili odmah popunim neku public static refernecu. Zavisi od slučaja do slučaja.
[ rj444 @ 08.06.2007. 12:35 ] @
Posto je ovo akademska rasprava pokusacu da dam svoje vidjenje problema.
Moje misljenje je da to ne moze da se uradi koriscenjem trenutne implementacije programskog jezika Java. Bar ne moze da se uradi elegantno i efikasno da bi imalo vise smisla od prosledjivanja reference this. U jeziku Java bi mogla da se definise referenca, nazovimo je caller poput this. Ta referenca bi dobijala vrednost u runtime-u pri kreiranju konteksta poziva metode (poput predavanja stvarnih argumenata). To bi bio posao za JVM ili bi se to moglo odraditi pomocu nekakvog glue koda koji bi kompajler generisao, a koji bi bio smesten pre prve naredbe metode. Medjutim cini mi se da ovakvo resenje ne bi bilo dovoljno efikasno zbog povecanja bajt koda ili zbog usporavanja izvrsenja usled odredjivanja adrese caller objekta. Takodje javlja se problem prepoznavanja klase objekta caller. Tu bi moglo da dodje do bacanja izuzetka ClassCastException sto bi zahtevalo da se svako koriscenje reference caller zastiti try catch blokom. To bi dosta zamaglilo kod metode. [ Java Beograd @ 11.06.2007. 08:52 ] @
Sasvim. Nemojmo smetnuti s' uma i konkurentno izvođenje toka programa. I ako, na primer, metod nije deklarisan kao synchronized već je otvoren za multuthread izvršavanje, u istom trenutku može biti više pozivnih klasa. Šta onda ?
[ anon315 @ 11.06.2007. 10:53 ] @
E da, to je dobro pitanje!
[ leka @ 11.06.2007. 13:59 ] @
Ok kakvom metodu se radi? Statickom? Ako ja dobro razumem pitanje onda sam malo zbunjen, jer ako nije staticki onda ti je objekat koji poziva metod uvek poznat (jer ces uvek pozivati metod sa objekat.metod() ). Ako se radi o statickom metodu, onda moras da predas this ako zelis da znas koji objekat ga je pozvao.
Pade mi na pamet nesto... Jedini nacin da se ovo odradi je najverovatnije da se koristi JAVA Debugging API. Pomocu njega vrlo verovatno mozes dobiti referencu na objekat koji poziva metod. Ne secam se kako, ali mozes naci u dokumentaciji. :) [ anon315 @ 11.06.2007. 16:55 ] @
Citat: leka: Ok kakvom metodu se radi? Statickom? Ako ja dobro razumem pitanje onda sam malo zbunjen, jer ako nije staticki onda ti je objekat koji poziva metod uvek poznat (jer ces uvek pozivati metod sa objekat.metod() ). Ako se radi o statickom metodu, onda moras da predas this ako zelis da znas koji objekat ga je pozvao. Ne radi se o statickom metodu. Pa da, ali ovde se radi o tome "odakle ti je poznat". Treba da ti bude poznat u okviru koda pozvane metode, a ne iz koda koji pozvao metodu pomenutog objekta. Citat: Pade mi na pamet nesto... Jedini nacin da se ovo odradi je najverovatnije da se koristi JAVA Debugging API. Pomocu njega vrlo verovatno mozes dobiti referencu na objekat koji poziva metod. Ne secam se kako, ali mozes naci u dokumentaciji. :) Posto je pitanje teorijskog tipa, pogledacu ako postane prakticnog tipa :))) [ filmil @ 11.06.2007. 18:08 ] @
Šta bi ti tačno da dobiješ?
Tvoj primer (http://www.elitesecurity.org/p1598503) može da se uradi bez gimnastike koju si predložio. Proslediš klasi B ne this, već referencu na privatnu instancu nekog unapred definisanog interfejsa. Onda lepo zoveš u interfejsu do mile volje metode koje hoćeš, a klasa A nema uslov da nasleđuje išta posebno. Code: public interface Foo { public void method(); } public class A { public void foo(B b) { b.bar(new Foo() { public void method() { foo2(); // Ili šta ti već treba. } }); } public void foo2() {} } public class B { public void bar(Foo f) { f.method(); }} f [Ovu poruku je menjao filmil dana 11.06.2007. u 19:43 GMT+1] [ anon315 @ 11.06.2007. 19:14 ] @
Cao Filipe, dugo te nije bilo... :)
Citat: Šta bi ti tačno da dobiješ? Nista specijalno, u tome je stos ;) Ako uzmemo u obzir da je ovo teorijska rasprava i da je poenta bila da "kod sam auto magicno nekako shvati ispod haube ko ga je pozvao" odnosno da ne mora da se predaje nista, onda mozemo da kazemo da je tvoje resenje znatno kompleksnije od polaznog, "problematicnog" koda ovog tipa: Code: public class A { public void foo(B b) { b.bar(this); } public void foo2() {} } public class B { public void bar(A a) { a.foo2(); } } [ hyle @ 11.06.2007. 22:15 ] @
U C++ se u stack frame-u, između ostalog, nalazi i this pointer i može se koristiti kao bilo koja druga lokalna promenljiva. Ne znam kako Java to radi ali verovatno ima neki sličan mehanizam.
Bilo bi zanimljivo da postoji caller pointer koji bi pokazivao na objekat koji je inicirao metodu. Pitanje je samo šta sa metodama koje se pozvane iz neke statičke metode, npr. iz main(), tu ne postoji objekat koji poziva metodu. Možda bi moglo nešto da se "izmajmuniše" pomoću AOP-a. U svakom slučaju, klase čije metode treba da budu svesne pozivaoca morale bi da imaju promenljivu (ThreadLocal) koja bi se koristila za čuvanje reference pozivaoca. [ filmil @ 11.06.2007. 22:24 ] @
Citat: Cao Filipe, dugo te nije bilo... :) Izvinjavam se, bio sam zauzet. Citat: haube ko ga je pozvao" odnosno da ne mora da se predaje nista, onda mozemo da kazemo da je tvoje resenje znatno kompleksnije od polaznog, "problematicnog" koda ovog tipa: Zavisi šta želiš da dobiješ. „Jednostavnije“ rešenje koje navodiš zahteva da objekat prosleđen klasi B bude ili klase A ili neke koja je nasleđuje (tj. „? extends A“) da bi program mogao da se prevede. To bez potrebe tesno spreže A i B. Takav kod ne bih pisao ako baš ne moram. „Komplikovanije“ rešenje ne zahteva da objekat klase A bude objekat nijedne posebne klase. Za čistunce, i poziv metoda foo2 može da se ubaci (inline) u bezimeni objekat. Onda je rešenje prostije, ali manje liči na tvoj primer odozgo. Krajnji rezultat mogućnost da se pozove neki određeni metod u klasi „iznad“. Ali ovde objekti klasa A i B uopšte nisu spregnuti. B može da se koristi i sa nekakvom klasom C koja radi na isti način. Ovakav kod bih pisao, i to često činim. Ovako se postiže cilj kog si čini mi se zadao — da metod iz klase B pozove određeni metod klase A. Ali ti si naveo još jedan uslov koji uopšte nije nužan, da prvo sazna koji je objekat pozvao a tek onda da se metod pozove. Na sličnu temu: http://en.wikipedia.org/wiki/Visitor_pattern f [ leka @ 13.06.2007. 16:37 ] @
Okej, problem je bio sto nisam shvatio poentu pitanja. :) Sada sam lagano prosao kroz pitanje i video da je ono zapravo cisto teorijsko - covek zeli da zna odakle JAVA "cupa" this, i kako uvek "zna" sa kojom referencom da zameni neko "this" u kodu...
hyle je vec objasnio ovaj mehanizam. Svi OO jezici koriste nesto slicno. Najprostije receno, kada kompajler naidje na objekat.metod(arg1, arg2); onda on to interno, dakle "iza zavese", transformise u funkcija(&objekat, arg1, arg2) . Uvek je lepo to videti na konkretnom primeru (kako recimo nasledjivanje radi itd.), tako da preporucujem odlican clanak http://www.eventhelix.com/Real...mparingCPPAndCPerformance2.htm , iako nema veze sa JAVOM. Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|