PDA

View Full Version : Wrapping static classes in Java



EtienneK
14-07-2008, 03:28 PM
Hey,

A friend and I have started writing a little game engine in Java. We found a nice OpenGL library for Java, but we want to wrap it using abstract classes. The problem is, there is no good way of wrapping static classes and methods in Java. The best ways we could come up with was using reflection (which is slow and the code is ugly) or making the child class that inherits the abstract class a singleton.

Anyone have experience in doing this in Java? A nice and elegant solution would be helpful :)

dislekcia
14-07-2008, 04:17 PM
My Java days are long past, but do the classes have to be static? Surely you can get away with static members and the singleton approach?

Squid's up to speed on Java, when he's done writing exams I'm sure he'll have something to add.

-D

EtienneK
14-07-2008, 08:18 PM
I think the best way to do this is:



public abstract class MyAbstractGraphicsClass {
public abstract void glClearColor(float r, float g, float b, float a);
}




public class WrapTheGraphicsLib extends MyAbstractGraphicsClass {

private WrapTheGraphicsLib instance = null;

private WrapTheGraphicsLib() { } // singleton

public WrapTheGraphicsLib getInstance() {
if (instance == null) {
instance = new WrapTheGraphicsLib();
}
return instance;
}

public void glClearColor(float r, float g, float b, float a) {
GL11.glClearColor(r, g, b, a); // this is a static method of the library I am wrapping
}
}


Anyone have a better solution?

ShadowMaster
14-07-2008, 09:56 PM
Perhaps
Surely it would be slightly better to do this(note I've added in statics that as far as I know should have been there anyway):



public class WrapTheGraphicsLib extends MyAbstractGraphicsClass {

private static WrapTheGraphicsLib instance = new WrapTheGraphicsLib();

private WrapTheGraphicsLib() { } // singleton

public static WrapTheGraphicsLib getInstance() {
return instance;
}

public void glClearColor(float r, float g, float b, float a) {
GL11.glClearColor(r, g, b, a); // this is a static method of the library I am wrapping
}
}


That should speed up the getInstance() method or if you want to get rid of the method call all together try this:



public class WrapTheGraphicsLib extends MyAbstractGraphicsClass {

private static WrapTheGraphicsLib instance = new WrapTheGraphicsLib();

private WrapTheGraphicsLib() { } // singleton

public static void glClearColor(float r, float g, float b, float a) {
instance.glClearColor_imp(r, g, b, a);
}

private void glClearColor_imp(float r, float g, float b, float a) {
GL11.glClearColor(r, g, b, a); // this is a static method of the library I am wrapping
}
}


In this case the implementation method is pointless but it serves as an example. So now instead of: WrapTheGraphicsLib.getInstance().glClearColor(...) you can go WrapTheGraphicsLib.glClearColor(...)

As to which is faster of the two I have no clue, but I can tell you clients would appreciate the latter approach more, but I'm all ears on any criticisms anyone has. Would serve as a learning experience.

PS what exactly is a reflection? Never heard the term used...

EtienneK
14-07-2008, 10:39 PM
Hmm, I like.

Always good to learn of new methods of doing things :) The way I did it in my post is how we do it at work, but your methods look pretty good as well.

As for reflection, I'll let Wikipedia do the talking:


In computer science, reflection is the process by which a computer program can observe and modify its own structure and behaviour. The programming paradigm driven by reflection is called reflective programming.

Link: http://en.wikipedia.org/wiki/Reflection_(computer_science)

Here's some documentation from Sun on how to use reflection in Java:
http://java.sun.com/developer/technicalArticles/ALT/Reflection/index.html

Here's the Java Reflection package: http://java.sun.com/javase/6/docs/api/java/lang/reflect/package-summary.html



EDIT: PS. Oops, yes. You were right about the statics. Sorry about that :)

EtienneK
14-07-2008, 11:48 PM
One question:

In your second implementation, how would you go about calling

public void glClearColor(float r, float g, float b, float a)
?
class WrapTheGraphicsLib can't be instantiated...

You would need the getInstance() method.

ShadowMaster
15-07-2008, 07:03 AM
Yeah I made a mistake with the statics in the second one... Sorry about that.

I fixed it, but here is the fixed version just in case:



public class WrapTheGraphicsLib extends MyAbstractGraphicsClass {

private static WrapTheGraphicsLib instance = new WrapTheGraphicsLib();

private WrapTheGraphicsLib() { } // singleton

public static void glClearColor(float r, float g, float b, float a) {
instance.glClearColor_imp(r, g, b, a);
}

private void glClearColor_imp(float r, float g, float b, float a) {
GL11.glClearColor(r, g, b, a); // this is a static method of the library I am wrapping
}
}


But the problem I have with singletons is you can just make everything static, privatise the constructors and get the same effect. Which is much easier.