I have a couple of Java questions while I am struggling making the switch from objective c to java:
1. In Java, static methods when implemented in derived classes are hidden, not overridden. If I have a method foo() in class A and B. I believe that execution of the code:
will execute method foo() in class A. That causes me a problem because if I use factory methods in classes, for each subclass I implement and want to instantiate with a factory static method, I need to reimplement the static factory method. I forget one and I get the superclass instead of the derived class! I was wondering how people solved this with or without reflection (I am okay paying the performance toll at object creation using java reflection for the convenience benefit).
2. I am trying to replicate the easy functionality of the NSClassFromString method in Cocoa. Basically, if I have a string for a full qualified class name, what is the best way to invoke a static method with a known signature for that class.
In objective c:
then you can call method
on class Bar with [foo() sna:d]
So far in Java using reflection, I came up with this convoluted code and it still doesn't replicate the behavior for the parameters for the function (I pass back the object reference, not the method back, therefore I also have to pass the parameter to call the method):
It works but it's heavy and not pretty. I understand that leaving a dynamic language like objective c , I have to make some compromises,
but I may miss something about Java for not having found something more lightweight for such a generic programming functionality. Any
suggestions to simplify this ugly implementation are welcome.
unfortunately I don't really understand all of your questions/problems (maybe because I don't know Objective C), but I hope I can shed light on some of your problems...
That's exactly the way you want it to work to take advantage of polymorphism. Only the methods of the declaration type (class A) are accessible, even though you assigned it an object of type B. This is usually how it should work because you just want SOME implementation of type A so that you can change it easily later. You can directly check for the real type and explicitly cast the variable b to type B, but then your code directly depends on type B which is not what you want with polymorphism. Perhaps a real world example to make the concept clearer to you: Say you want just some kind of "list" but you don't care about how the list is implemented and you want to be able to switch easily to another implementation which fits your needs better. Then you would say for example
That way you can only use the methods declared in the List interface directly but that's usually enough for most cases. But the big advantage is that your code doesn't depend on the concrete implementation type "ArrayList".
2. It would be easier to answer this question if I would know what you're really trying to achieve with this. Generally I'd say that it's not a good idea to use too much reflection features with method names encoded in strings. Reflection definitely has its place but you should be aware of the disadvantages. It hides a lot of your real code functionality from the compiler or IDE and makes the code much harder to understand for others. What's your point to search for methods with a specific signature that way? For me it seem that you want to try to mimic the behavior of dynamically typed languages in Java which is statically typed, right? Well, then you should probably rather go with dynamic languages instead or try to find concepts which still fit your needs but are used the "Java way". But for this discussion it would be useful to know the real reasons why you want to do this. Probably I'm not that experienced with dynamic languages but I'm sure it wouldn't be a good idea to use the wrong tool or the wrong concepts and try to make Java what it is not - a dynamic language.
Joined: Jul 15, 2004
Marco, thank you very much for your reply. I sincerely appreciate it.
Regarding 1) I realize that I get access to the static method of the superclass without having to cast to its type. I am just contemplating getting rid of all the static factory methods because its a real burden to have to implement its of its children.
If I create a new class C extending B and forget to add the newInstance implementation in C, I get a B class returned. That's very hard to debug, and the worse part is that I don't have a mean to force implementation of static methods.
Regarding 2) I have a list of classes simulating special effects all inherited from the same base class Effect: I have a FadeEffect, a GlowEffect, etc... Each class implements a static factory method newInstance to create the effect (ending up calling the constructore with more params that are needed for each effect.) What I am trying to do is to switch effects one by one and use it on the display. So I put all the effects names in an array, then create dynamically a class based on the strings I have stored in the array (with the reflection code above) and invoke the newInstance method on the current class/method discovered by reflection. I thought about creating the objects themselves in the array and scanning it at run time but it creates a lag at startup and bloat the code unnecessarily. Why should I store all the object while a string can do? Beside all the newInstance take the same parameters so if I want to change them, I'll have to change all the places creating all the effects. Right now, having all the effects in a string array is pretty convenient. I agree with you that reflecting is not perfect because it's essentially a workaround for what the language doesn't offer (or I am missing.) What is a better way to do this without reflection?
you're welcome ;-) But as I already said I'm not familiar with Objective C so please don't get me wrong if I may give you advices which may not make much sense to you. Also I have to admit that I'm not a big fan of dynamically typed programming languages so it's likely that I don't fully understand your problems simply because I haven't spend that much time for dynamic languages.
1) Basically there are two well-known factory patterns in Java. You can have either a factory method inside the class you want to create with that factory or you have a separate factory class which provides creation methods for all types of objects this factory can create. In your case you may have a factory class which has some method signatures like "public Effect createFadeEffect()" or "public Effect createGlowEffect()". You should already notice here that I use the same return value (which could be a common abstract concept like a Java interface or abstract base class if that's possible). And I would really create different methods for each type I want to produce but with more readable and understandable name.
Usually factories are only used if it would be too complex to create an object simply with a constructor, for example because it would require too many parameters. If you have to use factories it's always a little bit more ugly than with a simple call to the "new" operator. What I like about having a special factory class is that you have the ugliness at least all in one place.
If you really need or want factory methods there's probably no more elegant way than to create a static factory method in every concrete class. At least you could make one thing to enforce the creation methods and use an interface with the creation methods which all Effect classes would have to implement. As you already mentioned it doesn't make sense anyway to use inheritance because static methods don't benefit from inheritance.
2) I understand that it doesn't make sense to create all possible objects at startup. Especially if they are complex to create or consume many resources. But you shouldn't worry too much about object creation as modern JVMs are optimized to create new objects instead of pooling them like it was done for performance reasons with older Java versions. Despite this it's (in my opinion) definitely not worth the trouble to manage classes with their string names. I agree that you should not have to create all objects you possibly need at runtime but there are better ways than to remember their names as strings. If you use the factory concept properly you can delay object creation until you really need some object without having to give up type safety and IDE/compiler support (like you would do with using too much reflection).
For the problem with different signatures for the "newInstance()" methods you should think about the concept of a separate factory class like described above. If different effect classes require different parameters etc. there's no use to force them to implement the same creation method with the same signature. A factory class could serve your needs better in this case.
That said I should note that it's always hard to explain such topics which go beyond the Java language syntax here in a few sentences. I'd be happy to help you and discuss your problems but probably you have to be patient. It's even more difficult in this case because there are definitely concepts which can't be easily translated between the two programming languages.
In my opinion reflection is not the tool to use in this case. There are situations where reflection is a good choice but it should be possible to solve your problems without it. As I mentioned you would lose the biggest benefits of a statically typed language if you would deal with class and method names as strings.
Just feel free to ask about anything you like and I hope I can show you an alternative solution to your problem!