Martin Sturm: allereerst moet je weten dat ik een C++ developer ben in hart en nieren, en dat mijn focus voornamelijk op 3d computer graphics en andere gamedevelopment related zaken ligt.
Goed, allereerst is daar de algemene gedachtengang van Sun, die zo puristisch OO mogelijk moet zijn. Ik ben zelf iemand die vooral practisch ingesteld is, waardoor ik een hekel heb aan de omwegen die je soms moet nemen om je doel te bereiken. Ik neem als voorbeeld even de javax.vecmath package. In essentie is een vector wat anders dan een punt, daar ben ik het volledig mee eens. De eerste is een combinatie van richting en magnitude, terwijl de tweede juist een locatie in de ruimte aangeeft. Het inproduct op 2 punten bijvoorbeeld is an sich een onzinnige operatie, terwijl het op 2 vectoren daadwerkelijk wel betekenis heeft. Goed, wat doet Sun nu, die maakt een klasse Tuple, waar de coördinaten in zitten en basis-operaties als add, sub en scale. Een klasse Point extends Tuple met daarin een distance functie die de afstand tussen 2 punten kan berekenen, en een klasse Vector extends Tuple met operaties als het inproduct en uitproduct.
Welnu, als je bijvoorbeeld de afstand van een punt tot een vlak wilt berekenen, die gedefinieerd is als
(n ∙ p) - d, waarbij n de normaal is van het vlak, d de afstand van het vlak tot de oorsprong, en p het punt, dan kan dat dus niet direct in java: n is een Vector, terwijl p een Point is, en er is geen operatie Vector.dot (Point) of Point.dot (Vector) (er bestaat alleen een Vector.dot (Vector)). Je moet dus een nieuw Vector object aanmaken uit het punt (wat gelukkig dan weer wel kan, hoewel je het in feite gewoon niet moet gebruiken als je efficiente code wil schrijven), of handmatig de operatie van het inproduct specificeren, dus n.x * p.x + n.y * p.y + n.z * p.z (in 3d iig). Mijn idee: gooi gewoon alles in Vector, of iig alles in Tuple zodat je wel alle operaties kunt gebruiken. Het is verdomme bedoeld voor gebruik in performace-cricital applicaties, niet voor een OO walhalla oid
Dan komen we gelijk op het tweede punt: het aanmaken van objecten. Java kent geen user-defined value-types, dus als je een object nodig hebt die je in C++ typisch op de stack zal alloceren, zit je in java continu te new'en. Of tenminste, eigenlijk niet, in mijn eerder geposte applet maak ik overal van tevoren waar ik ze nodig heb temporary vertices en matrices aan, zodat ze direct bruikbaar zijn. Dit is enorm omslachtig, en elke keer als je weer een nieuwe nodig hebt betekent dat weer in je class declareren en alloceren. Buiten dat zijn objecten dmv references sowieso al trager omdat de compiler niet uit kan sluiten dat een instantie ook daadwerkelijk van dat type is, en niet van een subclass ervan oid. Plus het feit dat alles via een pointer moet, via de stack had je er direct bij gekunt.
Het volgende punt is het missen van by-reference passen van primitives. Als een functie meerdere returnwaarde heeft, bijvoorbeeld 2 ints, dan moet je daarvoor een object alloceren. Dat is dramatisch inefficient, als je nou gewoon een van de ints by-reference door kon geven dan had je helemaal geen object hoeven alloceren en had de aangeroepen functie direct de waarde van de int in de aanroepende functie kunnen wijzigen.
Operator overloading is ook iets wat ik enorm mis, maar is niet onoverkomelijk, en templates/generics is iets wat officieel komt in 1.5 en al beschikbaar was dmv een 3rd party compiler, dus daar zal ik niets over noemen.
Natuurlijk besef ik ook wel dat Java geen native taal is, maar als ik het zet tegenover .Net van microsoft dan denk ik toch van: ja, maar het kán dus wel!
.edit: oh, deterministic finalization is ook iets wat ik mis in Java. .Net krijgt dit overigens wel in de volgende update
[
Voor 4% gewijzigd door
.oisyn op 30-03-2004 15:34
]