/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
Et af de der underlige java spørgsmål der ~
Fra : Michael Berg


Dato : 06-03-03 22:00

Hej Alle,

Jeg har en klasse med en statisk metode:

package min.pakke;
public MyClass {
public static void doSomething();
}

Godt så. Et andet sted i koden har jeg brug for at kalde den statiske metode udfra et klassenavn (dvs. dynamisk), men uden at instantiere objektet. Dvs. den gode gamle

Class.forName("min.pakke.MyClass").newInstance().doSomething();

Duer ikke, for her får jeg jo netop lavet en instans. Så opgaven går altså ud på at give programmøren muligheder svarende til:

min.pakke.MyClass.doSomething();

Med den undtagelse at klassen skal kunne loades dynamisk - eksempelvis:

getMyClass().doSomething();

En lille ekstra krølle er at det selvfølgelig skal virke med afledte udgaver af MyClass.

Jeg ved faktisk ikke engang om java syntaksen sprogmæssigt giver mulighed for konstruktioner af denne type - i hvert fald ikke med compile time check af syntaks, metodenavne osv. Man kan sagtens gøre det med reflection (getMethod osv), men jeg synes det bliver lidt rodet hvis der fx. er dusinvis af statiske metoder i klassen. Jeg ville meget hellere kunne returnere en "klasse" som jeg så kan kalde de statiske metoder på, direkte.

Nogen der har nogle kommentarer omkring denne problemstilling? Not possible?

(Man kan sige jeg spørger om det er muligt at lave følgende: new getMyClass() ... jeg er selv skeptisk men I får lige chancen ..

Med venlig hilsen,
Michael Berg
www.key2know.dk


 
 
Rolf E. Thorup (06-03-2003)
Kommentar
Fra : Rolf E. Thorup


Dato : 06-03-03 22:38

Michael Berg wrote:

> Hej Alle,
>
> Jeg har en klasse med en statisk metode:
>
> package min.pakke;
> public MyClass {
> public static void doSomething();
> }
>
> Godt så. Et andet sted i koden har jeg brug for at kalde den statiske
> metode udfra et klassenavn (dvs. dynamisk), men uden at instantiere
> objektet. Dvs. den gode gamle
>
> Class.forName("min.pakke.MyClass").newInstance().doSomething();
>
> Duer ikke, for her får jeg jo netop lavet en instans. Så opgaven går
> altså ud på at give programmøren muligheder svarende til:
>
> min.pakke.MyClass.doSomething();
>
> Med den undtagelse at klassen skal kunne loades dynamisk - eksempelvis:
>
> getMyClass().doSomething();
>
> En lille ekstra krølle er at det selvfølgelig skal virke med afledte
> udgaver af MyClass.
>
[SNIP]

Jeg er ikke helt sikker på at jeg forstår dit spørgsmål: Finten ved
statiske metoder er jo netop at man ikke kalder dem på "objektniveau",
men på "klasseniveau". Dvs. følgende compiler og kører fint:

public class StaticTest {

public static void main(String[] args) {
StaticThing.testStatic();
}

}

class StaticThing {

public static void testStatic() {
System.out.println("Virker dette?");
}
}

rolft@Rudiger/kode/java$ java StaticTest
Virker dette?

Dvs. jeg kalder den statiske metode udfra et klassenavn.

Hvis det ikke var det du tænkte på, så ved jeg ikke helt hvad du mener.
måske er det noget med at det kun er muligt at instantiere eet objekt?
Dette kan opnås ved at lade constructoren være private og returnere den
samme reference hvergang en getInstance() metode kaldes:

private RegistryClient(String host, int port) {
[SNIP noget kode, men bemærk private constructor]
}

private static RegistryClient rc =
new RegistryClient(Address.getHostServer(),Address.getPortServer());

public static RegistryClient getReg() { return rc; }

/Rolf


--
"A good magician never reveals his secret; the unbelievable trick
becomes simple and obvious once it is explained. So too with UNIX."

Kenneth Egholm (07-03-2003)
Kommentar
Fra : Kenneth Egholm


Dato : 07-03-03 17:19

"Rolf E. Thorup" <rolfrolf@hotmail.com.invalid> wrote in message
news:3e67be75$0$25837$ba624c82@nntp03.dk.telia.net...

> Hvis det ikke var det du tænkte på, så ved jeg ikke helt hvad du
mener.
> måske er det noget med at det kun er muligt at instantiere eet objekt?
> Dette kan opnås ved at lade constructoren være private og returnere
den
> samme reference hvergang en getInstance() metode kaldes:

Yep, det hedder SingletonPattern..

Men jeg tror det er dit afsnit 1 i svaret han tænker på.. Omend det er
oplagt.. Ellers forstår jeg heller ikke spørgsmålet..

--
MVH Kenneth Egholm



Rolf E. Thorup (07-03-2003)
Kommentar
Fra : Rolf E. Thorup


Dato : 07-03-03 20:29

Kenneth Egholm wrote:
> "Rolf E. Thorup" <rolfrolf@hotmail.com.invalid> wrote in message
> news:3e67be75$0$25837$ba624c82@nntp03.dk.telia.net...
>
>>Hvis det ikke var det du tænkte på, så ved jeg ikke helt hvad du
>
> mener.
>
>>måske er det noget med at det kun er muligt at instantiere eet objekt?
>>Dette kan opnås ved at lade constructoren være private og returnere
>
> den
>
>>samme reference hvergang en getInstance() metode kaldes:
>
>
> Yep, det hedder SingletonPattern..
>
Jep, I know, men tænkte at det var nok ikke det OP ledte efter alligevel
så nævnte det ikke.

> Men jeg tror det er dit afsnit 1 i svaret han tænker på.. Omend det er
> oplagt.. Ellers forstår jeg heller ikke spørgsmålet..

God Weekend... /Rolf


Mikkel Bundgaard (06-03-2003)
Kommentar
Fra : Mikkel Bundgaard


Dato : 06-03-03 23:55

On Thu, 06 Mar 2003 22:00:06 +0100, Michael Berg wrote:

> Hej Alle,
>
> Jeg har en klasse med en statisk metode:
>
> package min.pakke;
> public MyClass {
> public static void doSomething();
> }
>
> Godt så. Et andet sted i koden har jeg brug for at kalde den
> statiske metode udfra et klassenavn (dvs. dynamisk), men uden
> at instantiere objektet. Dvs. den gode gamle
>
> Class.forName("min.pakke.MyClass").newInstance().doSomething();
>
> Duer ikke, for her får jeg jo netop lavet en instans. Så
> opgaven går altså ud på at give programmøren muligheder
> svarende til:
>
> min.pakke.MyClass.doSomething();
>
> Med den undtagelse at klassen skal kunne loades dynamisk - eksempelvis:
>
> getMyClass().doSomething();
Dette er bare et skud fra en træt person, der ikke har tænkt nærmere over
problemet (og ikke er helt sikker på at han forstår det helt )

Brug metoden getMethod(String name, Class[] parameterTypes) eller
getDeclaredMethod i klassen Class. Dette skulle gerne returnere den
rigtige Method. I denne klasse kan du så bruge metoden invoke(Object obj,
Object[] args) til at kalde metoden.

Citat fra JavaDocen om invoke
"If the underlying method is static, then the specified obj argument is
ignored. It may be null."

> En lille ekstra krølle er at det selvfølgelig skal virke med
> afledte udgaver af MyClass.
Ifølge Javadocen for getMethod så burde det virke (hvis jeg har forstået
spørgsmålet rigtigt)
"1. C is searched for any matching methods. If no matching method is
found, the algorithm of step 1 is invoked recursively on the superclass of C.
2. If no method was found in step 1 above, the superinterfaces of C are
searched for a matching method. If any such method is found, it is
reflected."

--
Mikkel Bundgaard
Student at IT University of Copenhagen
Codito, Ergo Sum

Michael Berg (07-03-2003)
Kommentar
Fra : Michael Berg


Dato : 07-03-03 22:07

Hej Alle,

"Mikkel Bundgaard" <mikkelbu@teliamail.dk> wrote in message news:pan.2003.03.06.22.55.03.53974@teliamail.dk...

> Dette er bare et skud fra en træt person, der ikke har tænkt nærmere over
> problemet (og ikke er helt sikker på at han forstår det helt )
>
> Brug metoden getMethod(String name, Class[] parameterTypes) eller

Ja - det er selvfølgelig en løsning (jeg mener jeg selv foreslog man kunne bruge reflection til det). Det er bare lidt klodset og omstændeligt synes jeg. Og lad os ikke glemme at reflection er noget nær det langsomste man kan foretage sig i Java ...

Problemet er at jeg har en klasse med en statisk metode, men klassens navn kendes først på runtime tidspunktet. Jeg kan godt gøre følgende:

MinKlasse k = (MinKlasse)Class.forName(den_dynamiske_klasse).newInstance();
k.minStatiskeMetode();

Mit problem er bare at MinKlasse laver en masse ting i sin Constructor. Jeg er derfor ikke interesseret i at instantiere objektet, hvilket newInstance() jo netop gør.

Det eneste jeg gerne vil er at kalde en statisk metode på klassen - UDEN at lave en instans af den. Og ja, du har nok ret i at jeg er nødt til at gå via reflection (getMethod osv), men det er altså ikke særlig smart hvis man nu har 50 statiske metoder med forskellige parametre osv. Her ville det have været super praktisk hvis man fx kunne sige (og nu opfinder jeg lige en syntax):

((MinKlasse)Class.forName(klassenavnet)).statiskMetode(parm1, parm2);

Meeen. Jeg tror desværre ikke Java tillader den slags krumspring.

Anyway - jeg har løst det på en anden måde. Men tak alligevel.

Mvh
Michael Berg
www.key2know.dk


Mikkel Bundgaard (07-03-2003)
Kommentar
Fra : Mikkel Bundgaard


Dato : 07-03-03 23:06

On Fri, 07 Mar 2003 22:07:20 +0100, Michael Berg wrote:

> "Mikkel Bundgaard" <mikkelbu@teliamail.dk> wrote in message
> news:pan.2003.03.06.22.55.03.53974@teliamail.dk...
>
>> Dette er bare et skud fra en træt person, der ikke har tænkt nærmere
>> over problemet (og ikke er helt sikker på at han forstår det helt
>> )
>>
>> Brug metoden getMethod(String name, Class[] parameterTypes) eller
>
> Ja - det er selvfølgelig en løsning (jeg mener jeg selv foreslog man
> kunne bruge reflection til det). Det er bare lidt klodset og omstændeligt
> synes jeg. Og lad os ikke glemme at reflection er noget nær det
> langsomste man kan foretage sig i Java ...
Jeg var kommet til at slå "wrap article body" fra, og dermed så din besked
ud til at bestå af en masse _meget_ lange linjer. Derfor tror jeg, at jeg
ikke læste den særligt grundigt . Selvom Reflection i Java er
langsommere end direkte kald, så tror jeg ikke, at det er noget der kan
mærkes. Så vidt jeg husker så drejer det sig om en faktor 2 eller 3.

> Det eneste jeg gerne vil er at kalde en statisk metode på klassen - UDEN
> at lave en instans af den. Og ja, du har nok ret i at jeg er nødt til at
> gå via reflection (getMethod osv), men det er altså ikke særlig smart
> hvis man nu har 50 statiske metoder med forskellige parametre osv. Her
> ville det have været super praktisk hvis man fx kunne sige (og nu
> opfinder jeg lige en syntax):
>
> ((MinKlasse)Class.forName(klassenavnet)).statiskMetode(parm1, parm2);
Du kunne vel bare lave en metode i et util objekt, som tog mod klassenavn
og paramtre og som så skjulte det beskidte arbejde fra brugeren.

> Meeen. Jeg tror desværre ikke Java tillader den slags krumspring.
Næ ikke direkte

> Anyway - jeg har løst det på en anden måde. Men tak alligevel.
Så er der jo ingen problemer.
--
Mikkel Bundgaard
Student at IT University of Copenhagen
Codito, Ergo Sum

Søg
Reklame
Statistik
Spørgsmål : 177491
Tips : 31966
Nyheder : 719565
Indlæg : 6408455
Brugere : 218886

Månedens bedste
Årets bedste
Sidste års bedste