Win a copy of TDD for a Shopping Website LiveProject this week in the Testing forum!
  • 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
  • Paul Clapham
  • Ron McLeod
  • Jeanne Boyarsky
  • Tim Cooke
Sheriffs:
  • Liutauras Vilda
  • paul wheaton
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Frits Walraven
Bartenders:
  • Piet Souris
  • Himai Minh

Determining where static is running

 
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Don't know if this is possible but I have a static method which is inherited into many subclassess. Is there a way of the static determining in which class it is running. I know you can do a getClass() on an instance but what can you do in a static method to work out the same?
TIA Graham
 
Ranch Hand
Posts: 180
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I may be reading your question wrong, but I am pretty sure that you cannot inherit static members...
however, more to your question, you can use the reflection (java.lang.reflect) API to retrieve a list of all fields in a class (static or otherwise).
Hope this helps.
 
Ranch Hand
Posts: 109
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Chris is correct, static methods are not inherited. Which implementation gets called depends on the declared type of the object so this code:

Prints:
Parent
Child
Parent
Child
Parent

Also note that if inside Child.method(), I had tried to call super.method(), I would get this compiler error:
Test.java:11: non-static variable super cannot be referenced from a static context
super.method();

So the direct answer to your question Graham is it will be whichever class you declared the instance to be (probably the top level parent class, in which case you're always running the same implementation).
Pete
(SCJP, SCJD)
 
Ranch Hand
Posts: 327
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just wanted to comment how clear this example is. I never thought of using the obvious names, Parent and Child, as you did. What a great teaching example!
I don't see what is not static, however, with the call you mentioned would result in the error. Can you explain?
Great example,
Betty
 
"The Hood"
Posts: 8521
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hmmmm. . . static members (both variables and methods) ARE inherited by subclasses.
From the JLS 8.4.6 Inheritance, Overriding, and Hiding

A class inherits from its direct superclass and direct superinterfaces all the non-private methods (whether abstract or not) of the superclass and superinterfaces that are accessible to code in the class and are neither overridden (�8.4.6.1) nor hidden (�8.4.6.2) by a declaration in the class.


Static initializers blocks are not.
Static methods are resolved at compile time and therefore do not participate in polymorphism - but that does not mean that they are not inherited, just that they are not dynamically resolved at runtime.
Because static methods are not ever overridden (something that requires polymorphism) - if the subclass prevents the static method from being inherited by having it's own method with the same signature there is a different word for the situation. This is called hiding instead of overriding. Hiding prevents inheritance.
If you inherit the static method by a subclass - it is still "running" out of the class that declared the method.
You can not do anything "instance related" in the code inside a static method because this code can just as well be called without an instance of anything calling it.
From JCL 8.4.3.2 static Methods


A class method is always invoked without reference to a particular object. An attempt to reference the current object using the keyword this or the keyword super in the body of a class method results in a compile-time error.

 
Cindy Glass
"The Hood"
Posts: 8521
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
By the way, what Pete was showing is an example of "top level nested classes" - which I think is sort of confusing the question being asked. His example could just as easily have shown those classes declared outside the Test class but still having static methods in them.
But then I could be wrong about the question.
 
Pete Lyons
Ranch Hand
Posts: 109
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Cindy has a good clarification there. The "static" keyword means not dynamic (fixed at compile time) as opposed to the great polymorphism and "dynamic" method lookup we're used to in non-static methods. So yes, the methods are inherited such that you can invoke them through a reference to an instance of a subclass. So, if I deleted the declaration of the "method" method from the class Child, the code would still compile and run and produce this output:
Parent
Parent
Parent
Parent
Parent
Cindy, the top-level nested classes were literally just so I could get the code compiled and running as fast as possible; sorry if this makes the example more confusing. Same thing with declaring that main throws Exception, which I always do in test code to keep things simple.
Betty, it's the super keyword which would be considered non-static (it refers to a specific object instance). See the link Cindy referenced.
 
Graham Mead
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
Maybe I was a bit confusing with the question. Thanks for the replies though.
In a nutshell what I want to do is have a superclass called SuperClass1 with a public static method called say createYourself().
All subclasses of this WILL inherit this method.
I then want to be able to invoke the inherited method like:
SubClass1.createYourself();
And have this create an instance of SubClass1 returning it as type SuperClass.
Being lazy I don't want to implement this method in every subclass so I need a way within the createYourself() static method of working out in which subclass it is inherited and running. So that it can create the correct type.
Hope this makes sense, if not thanks for the input so far anyway :-)
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Graham Mead:
SubClass1.createYourself();
And have this create an instance of SubClass1 returning it as type SuperClass.


That's simply not possible - the above code will produce *exactly* the same byte code as
SuperClass1.createYourself();
Can you tell us more about *why* you want to do that? Perhaps you could make use of the Prototype pattern or the like?
 
Cindy Glass
"The Hood"
Posts: 8521
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What you are describing sounds to me like a constructor - not a static method.
If you create an instance of the subclass - it will execute the constructor for the superclass and return it as type subclass.
 
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It sounds like you may be trying to use the Singleton pattern. I don't think you can get around writing the createYourself() method for each subclass without using some other pattern. Perhaps the Factory or Factory Method patterns apply to your problem. If you don't understand design pattern terminology, you should probably get a book about it.
HTH
Layne
 
Graham Mead
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm swimming in books :-)
I was just trying to think through an alternative way of doing something which could quite easily not be possible.
I am using the frontcontroller pattern in a servlet/jsp mvc application which loads navigation data at system start up.
When a request comes in from the client its URL is used as a key to a hashtable to return an instance of a validator class to validate the request data.
As the application is multithreaded I want to always return a new instance.
So I could have the table as follows
Key1 "Fully qualified validator1 class name"
Key2 "Fully qualified validator2 class name"
etc and use reflection to create a new instance with the class name via a factory class.
or I could use
Key1 An instance of validator class 1
Key2 An instance of validator class 2
and have each validator implement an interface that defines a method that returns an new instance of itself, and probably there are 10 other ways.
One way that provoked the original question was to try
Key1 SubClass1.class - class objects
Key2 SubClass2.class
With SubClass1, 2 extending and inheriting from a SuperClass that had a static method defined that could somehow work out in which class it was inherited and return an instance of that SubClass with type SuperClass.
I'm getting the idea that this could be a ridiculous idea :-) but I just wanted to try it. Feel free to shoot me down in flames.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That is an interesting idea - but it isn't possible in Java, because classes aren't "first class objects" (your idea would work in Smalltalk, afaik).
You could make use of the Factory Pattern (instead of Validator1.class with a static factory method, use an extra Validator1Factory with an polymorphic instance factory method).
An easier solution could be the Prototype pattern (register an actual validator with each key, which you use as a "template" to clone instances from you actually work with).
Did that help?
 
Graham Mead
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ilja and everyone else
You've convinced me
Thanks a lot for the ideas.
I think its the Prototype pattern for me then
 
Bring out your dead! Or a tiny ad:
free, earth-friendly heat - a kickstarter for putting coin in your pocket while saving the earth
https://coderanch.com/t/751654/free-earth-friendly-heat-kickstarter
reply
    Bookmark Topic Watch Topic
  • New Topic