• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Static Problem

 
Ranch Hand
Posts: 226
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,

I have a problem that I�d appreciate your help in.
I�ll do my best to explain�

I have a MessageRetriever class that is used throughout the application to get messages. It is an abstract class that contains just static methods, and one static string defining where the file is held containing the messages. In one of these methods, the static string is used.

I now have a need to retain this functionality, but to use a different file (so a different value for the static String). I defined a new class that extended MessageRetriever (WebAppMessageRetriever), and in it just have the static string defined, pointing to the new file.

When I call methods on the WebAppMessageRetriever, the methods in the superclass are correctly invoked, but the static value in the superclass is used as well, totally ignoring the value in the child class.

I think the problem is related to the methods/values being static (and so �related to the class�) and so inheritance isn�t working as expected. This is further complicated by the fact that these classes never need to be instantiated, and so no constructors are ever called (values could be passed in).

I have so far tried:
Using a static initialiser in the child to set the value
Writing get methods in both classes, thinking that the parent would call the get method in the child
Removing the definition in the parent (compilation fails).

Suggestions?





Code called in app : WebAppMessageRetriever.getMessage()
Fails due to NullPointerException (value is not defined in parent class).

Thanks in advance,

Mark G
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"I now have a need to retain this functionality, but to use a different file (so a different value for the static String). I defined a new class that extended MessageRetriever (WebAppMessageRetriever), and in it just have the static string defined, pointing to the new file."

That does not work for two reasons: (1) member variables cannot be overridden and (2) static methods cannot be overridden.

(1) Member variables cannot be overridden just like you can override methods. So if you have a member variable called "x" in a superclass and also a member variable called "x" in a subclass of that superclass, then you have two different variables called "x". In the subclass, "x" hides the superclass version of "x". In the superclass, "x" always refers to the "x" in the superclass itself - it is not overridden by the "x" in the subclass.

(2) Likewise, static methods cannot be overridden.

There's no dynamic binding for member variables and static methods like there is for non-static methods.

To solve this:

First of all, you have to make all the methods non-static. Second, provide a method to get the name of the resource bundle instead of putting it in a variable:

[ March 23, 2007: Message edited by: Jesper Young ]
 
Mark Garland
Ranch Hand
Posts: 226
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Jesper,

Thank you for your quick reply.

Unfortunately, I would really like not to have to change these to non static. The class has been used throughout the project, and a quick count points to 130 usages. Going back and instantiating the object each of these times would take quite a bit of reworking!

One of my work colleagues suggested using the following approach:



This has solved the problem and it now appears to working fine.

Thanks once again,

MG
 
Ranch Hand
Posts: 131
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My advice is to make the class final, not abstract, and use static imports to get at the methods. Pass the methods anything they need, when you call them.
 
Mark Garland
Ranch Hand
Posts: 226
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Ricky,

Thanks for your reply.

Having shown my solution to some of my other colleagues, they were less than impressed. I was told that while what I have developed worked, it was potentially a bad solution as trying to implement any form of inheritance when it comes to static methods/parameters is a very dangerous game, because you can easily bypass all of the inheritance by calling methods on specific classes.

In the end, I took their (and Jesper's) advice, and made the methods non-static. This did require reworking, however I was shown that this could be achieved reasonably easily using our IDE.

However, to prevent having to instantiate the object 130 times, I was reminded of the Singleton pattern, meaning that I could still call a static method from my code, but could use non-static methods that could be correctly inherited.

Result:

WebAppMessageRetriever.getMessage("40"));
becomes
WebAppMessageRetriever.getMessageRetriever().getMessage("40"));
Not
WebAppMessageRetriever w = new WebAppMessageRetriever();
w.getMessage("40");

Hope that all makes sense,

Thanks for all your help everyone - been a learning curve!

MG



 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can you initialize that static string as part of startup? Just add a static setter and call it from your startup code before anybody tries to get a message? Then no clients have to change.
 
reply
    Bookmark Topic Watch Topic
  • New Topic