Calling a static method using generics or FooClass.CLASS? - java

I have the following base class
public class Car
{
public static int getWheelsCount()
{
return 4;
}
}
Then I have a few child classes extending from it with custom methods, e.g Honda extends Car, Mercedes extends Car, etc.
In a separate method, I simply want to be able to receive a particular sub-child of Car , either as generics or Honda.CLASS and call the getWheelsCount() method of it. Something like this:
public void doSomething<T extends Car>()
{
int wheels = T.getWheelsCount();
}
Or:
public void doSomething(Car myCar.CLASS)
{
int wheels = myCar.getWheelsCount();
}
I could call this function in this way:
doSomething<Honda>();
doSomething<Mercedes>();
or:
doSomething(Honda.CLASS);
doSomething(Mercedes.CLASS);
etc.
Any ideas how I can accomplish what I want here?

Since the static method is declared on Car, just always call:
Car.getWheelsCount();
Obviously, you don't mean for the method to be static, you want it to be a regular method, and have each car give it's answer independantly.... so, remove the 'static' from the method declaration, and have each Car subclass override the method.... then call the instance method for each car.

In Java, static methods cannot be overridden. This is mostly due to the fact that Java classes are not objects themselves, unlike a language like Objective-C, for example. Java class objects (instances of java.lang.Class) are wholly different things that are only part of Java's somewhat hacky reflection system.
While it's hard to give much advice without understand your purpose, I would advise that you attempt to eliminate static functionality from your Java classes as much as possible due to this limitation, unless the methods in question are utility or helper methods. Try to restructure your code to pass instances instead of classes.
With more information about the goal, rather than purely information about the problem you've had in implementing your particular solution, it may be easier to give a more specific and comprehensive answer.

Related

Is there a way to know what sub class is calling the super class?

This is a bit of the code i have. Both the Rabbit and Fox classes are sub classes of the super class and they each have a getCounter() method which returns an int. I get an error saying that getCounter() is not a valid method. I know that it doesnt exist in this current class but if the code executes getCounter would be accessible. (getCounter is static too).
public static String setGender(Object obj){
int specificCounter;
Class s = obj.getClass();
if(s == Fox.class|| s == Rabbit.class){
specificCounter = s.getCounter();
In object oriented programming languages such as Java, such problems are usually solved using polymorphism.
For instance, you could have the base class declare an abstract method, and provide separate implementations in each subclass.
The Java Tutorials I linked to contain an example on how to do this.
you can use instanceof for the class check (if(obj instanceof Fox)). But this will lead to many if elses if you have many different sub classes.
But the important thing is that you use polymorphism as mentioned by meriton. From your question I deduce that the provided code is in the super class of Fox and Rabbit, let's assume it's called Animal. Now you don't have to receive an Object, but you can receive an Animal. As long as the Animal class has the method getCounter() (which can even be overridden by the sub classes for more specific implementations), you can now call obj.getCounter()
class Animal {
public static String setGender(Animal obj){
int specificCounter = obj.getCounter();
}
}
As many others have pointed out, there seems to be quite a few problems going on here.
There doesn't seem to be enough information for any one person to help you out. Instead try reading up on how Java works.
java Class- https://docs.oracle.com/javase/tutorial/java/javaOO/index.html
java Inheritance- https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
java Oracle Documentation & Tutorials-https://docs.oracle.com/javase/tutorial/java/index.html
As mentioned by many others, the super class should stand on it's own, and be totally unaware of sub classes. Sometimes you "have" to do odd things like this, but it should avoided if possible. In a normal design there are 3 common approaches that would be acceptable:
Make "Animal" an interface, all logic would be in the
implementing classes of the interface
Declare Animal abstract, and make setGender abstract, fulling
implementing the code in the subclasses.
Likely best for this scenario: Override the "setGender()" method in
your subclasses, and perform any specific operations to the subclass
in there after calling the super.setGender(), if applicable.
Like so:
public class Fox extends Animal {
private String speciesGender;
#Override
public void setGender(String gender) {
super.setGender(gender);
//add specific stuff for fox
if(gender.equals("F")) {
speciesGender = "Vixen";
} else {
speciesGender = "Tod"
}
}
}
The getter for spceciesGender could be abstract in Animal as well forcing the creation of it. Lots of ways to slice it...

Work-around for assigning to this in Java?

After reading this thread, I understand that it is not possible to assign to this in Java. But are there any workarounds? I have the following situation. I'm writing a subclass B, but the base class A does not have any explicit constructors or methods that would allow to create the object given my arguments. The only available way is to call some external function F():
public class B extends A {
public B(some args) {
A a = F(some args);
this = a;
}
}
Both A and F() are from external libraries, A is a pretty complex object, and F() implements a sophisticated algorithm.
The only solution I can think of, is simply not to make a subclass:
public class B {
public A a;
public B(some args) {
a = F(some args);
}
}
It doesn't look very appealing though. What would be the least ugly solution in this situation?
Your solution to not make a subclass is correct one. That is composition, and you should always prefer it over inheritance. So even if A had the right constructor, you shouldn't make B a subclass of A unless you have a specific requirement forcing you to do it.
Only use inheritance when you need to pass instance of B as instance of A. But really, you should rarely need to do that, unless you are dealing with poorly designed code. You should use interfaces, so you would would have class A which implements some interface, let's call it interface IA. Then instead of being subclass of A, you simpley have class B implements IA. And then you have the private member variables of type A inside B, if you need it.
(There's also the matter of when to use interfaces and when to use abstract base classes, but I'll leave it out of this answer.)
Note that modern Java IDEs make creating delegates very easy, and frankly, coding Java without such IDE is wrong way to code Java. Writing all that boilerplate by hand is error-prone, tedious, and makes you hate Java for no reason. With modern IDE, first add that private member variable a, possibly place cursor on it or right click it for context menu, and find "Insert code..." or some such option. From there find something like "Add delegates...". Then you should simply be able to click which methods of A you want to add to B and have them delegated. The IDE should create code in B like this.
int method() {
return a.method();
}
This makes actually following "composition over inheritance" quite nice and easy.

Can I create static methods on #MappedSuperclasses?

I have an abstract TemporalModel class (annotated with #MappedSuperclass) that adds created and updated fields to all extending models. I want to add a getLatest() static method to it:
public static TemporalModel getLatest() {
return find("order by created").first();
}
When I put this method on the base class, and call it through a concrete class (Transaction.getLatest()), I get an error:
UnsupportedOperationException occured : Please annotate your JPA model
with #javax.persistence.Entity annotation.
I suspect this is because JPA doesn't in fact know I'm calling this method "through" the base class (there is no real static method inheritance in Java).
Is there another way to implement this method once, instead of repeating it on all entity classes?
Update - one way to achieve this (which I'm using in another heavier app) is described here (gist). In my current app, however, I wouldn't like to use repositories, and I wondered if there's another, lighter solution.
Constructors and static methods can never be abstract. The idea behind an abstract class
is to create blueprints of methods, that have to get worked out in the subclass(es). I suggest trying an interface TemporalModel instead of an abstract class, in which you create the method public static TemporalModel getLatest();
I haven't used this Play framework, so I'm not sure about the details here, but usually, when one does the stuff you want to do, in Java, one simply specifies the concrete class as a parameter to the static method in question. It's kind of ugly, of course, but it is Java.
I assume that this find method is a static method that is added somehow (by annotation processing?) by this framework on every extending class, right? In that case, I think your only recourse is to do something like this:
public static <T extends TemporalModel> T getLatest(Class<T> cl) {
try {
/* I don't know what type the find() method returns, so you'll have to fix the casting */
return(cl.cast(cl.getMethod("find", String.class).invoke("order by created").first()));
} catch(AllThosePeskyReflectionExceptions e) {
throw(new Error(e));
}
}
I think that's the best way available given the premises. I know it's ugly, so I'd be happy to be wrong. :)

Alternatives to abstract static/static override methods with generics in java

Ok so I know that you can't have an abstract static method, although I see this as a limitation personally. I also know that overriding static methods is useless because when I am dealing with say MyList<T extends ObjectWithId> and my object has an abstract class with a static method that gets overridden in it's subclasses, T doesn't exist at runtime so ObjectWithId's static method would be called instead of the subclass.
So here is what I have:
class PersistentList<T extends ObjectWithId> implements List<T>{
}
where ObjectWithId is:
abstract ObjectWithId{
public abstract long getId();
}
Now the issue is that my PersistentList is meant to be stored on hard disk, hence the name, and in reality will only store ids of objects it holds. Now when I want to implement the
#Override
public T get(int index) {
}
method of PersistentList, what I want is for my program to use the id it has stored for index and call a static method objectForId(long id) which would be implemented in each subclass of ObjectWithId. It can't be a instance method because there is no instance yet, the point is to load the instance from the hard disk using the id. So how should it be implemented? One option is to have ObjectWithId have a constructor ObjectWithId(long id) implemented in each subclass, but T doesn't exist at runtime so how would I instantiate it? I know I could pass Class<T> object in the constructor of PersistentList but I would prefer if the constructor did not have any arguments, but I don't think there is a way to get the class of T without explicitly passing it in right?
I hope this is a better explanation, sorry for the ambiguous question I started with.
While passing the Class<T> as a constructor argument, it does not really solves your problem. You then have access to the class, but to get access to the static method defined on the class you will have to use generics (unless somebody else knows a way to call a static method defined on a class from a Class object).
I would define a new generic interface which contains a generic method objectForID, something like
public interface ObjectRetriever<T>{
public T objectForID( long aID );
}
and adjust the constructor of the PersistentList to take such a ObjectRetriever instance as parameter. This ObjectRetriever can then be used to restore the objects based on their ID.
While it always seems easier to start out with static methods, I've found it to usually be beneficial to avoid static methods for just this reason, and to use instance methods by default.
The advantage to this is extensibility. Besides allowing for inheritance and avoiding the "limitations" you mentioned, it provides for extensibility - without needing to redesign things and change APIs later. For example, "this class does exactly what I need, but I wish I could change only this one portion of functionality". If there are static methods calling other static methods, there is no good way to do this. If all the methods are non-static - I can subclass that class and override only the portion of functionality required.
The other (somewhat-related) limitation to static methods is that they can't be used to implement interfaces.
In summary, I prefer to reserve static methods for "utility methods" where the function that they are performing is really clear-cut, and there isn't any feasible future reason why an alternative implementation would need to be provided.

Should Helper/Utility Classes be abstract?

I commonly find myself extracting common behavior out of classes into helper/utility classes that contain nothing but a set of static methods. I've often wondered if I should be declaring these classes as abstract, since I can't really think of a valid reason to ever instantiate these?
What would the Pros and Cons be to declaring such a class as abstract.
public [abstract] class Utilities{
public static String getSomeData(){
return "someData";
}
public static void doSomethingToObject(Object arg0){
}
}
You could just declare a private constructor that does nothing.
The problem with declaring the class "abstract" is that the abstract keyword usually means that class is intended to be subclassed and extended. That's definitely not what you want here.
Don't bother making them abstract, but include a private parameterless constructor to prevent them from ever being instantiated.
Point of comparison for those interested: in C# you would declare the class to be static, making it abstract and sealed (Java's final) in the compiled form, and without any instance constructor at all. That also makes it a compile-time error to declare a parameter, variable, array etc of that type. Handy.
I don't declare utility classes abstract, I declare them final and make the constructor private. That way they can't be subclassed and they can't be instantiated.
public final class Utility
{
private Utility(){}
public static void doSomethingUseful()
{
...
}
}
I would add more step beyond the private constructor:
public class Foo {
// non-instantiable class
private Foo() { throw new AssertionError(); }
}
Throwing the AssertionError prevents methods in the same class from instantiating the class (well, they can try). This isn't normally a problem but in a team environment you never know what someone will do.
As regards the "abstract" keyword, I have noticed utilities classes subclassed in numerous instances:
public class CoreUtils { ... }
public class WebUtils extends CoreUtils { ... }
public class Foo { ... WebUtils.someMethodInCoreUtils() ... }
I believe this is done so that people don't have to remember which utility class to include. Are there any downsides to this? Is this an anti-pattern?
Regards,
LES
By declaring them as abstract, you are in effect indicating to other coders that you intended for these classes to be derived from. Really, you're right, that there's not much difference, but the semantics here are really more about the interpretation of other people who look at your code.
As others stated, make a private parameter-less constructor. No-one can create an instance of it, apart from the class itself.
As others have shown how it is done with other languages, here comes how you do it in the next C++ version, how to make a class non-instantiable:
struct Utility {
static void doSomething() { /* ... */ }
Utility() = delete;
};
I think it's better to declare utility classes final with a private no-args constructor. Moreover all members of this class should be static.
An easy way to do all this in one statement is to use the #UtilityClass annotation of Lombok:
#UtilityClass
public class Utilities{
public String getSomeData() {
return "someData";
}
public void doSomethingToObject(Object arg0) {
}
}
If you use the #UtilityClass annotation you can skip the static keywords as in the example above since Lombok adds them automatically during compilation.
No, but if your language supports it, there's a strong argument to be made that in most cases they should (can) be declared as 'static'... Static tells the compiler that they cannot be instantiated, and that all methods in them must be static.
Abstract is for classes that DO have instance-based implementation details, which WILL be used by instances of derived classes...
someone mentioned that in C# 3.0 you could accomplish this via extension methods. I'm not a C# guy, did some back in the 1.5/2.0 days, but have not used it since then. Based on a very cursory understanding I think something similar can be accomplished in java with static imports. I realize its not at all the same thing, but if the goal is to just make these utility methods seem a bit more "native"(for lack of a better term) to the calling class, I think it will do the trick. Assuming the Utilities class I declared in my original question.
import static Utilities.getSomeData;
public class Consumer {
public void doSomething(){
String data = getSomeData();
}
}
Might I offer some constructive advice?
If you are doing a lot of this, there are two problems you will run into.
First of all, a static method that takes a parameter should often be a part of the object that is that parameter. I realize this doesn't help for objects like String, but if it takes objects you've defined, you could almost certainly improve the object by including your helper as a method of that object.
If it takes all native values, you probably could define an object that it's a method of. See if you can find any grouping of those native values and group them as an object. If you just try that, you'll find a lot of other uses for that little mini-object, and before you know it it will be amazingly useful.
Another thing, if you have a utility class with a bunch of semi-related static methods and static variables, you almost always want it to be a singleton. I found this out by trial and error, but when you find out you need more than 1 (eventually you will), it's MUCH easier to make a singleton into a multipleton(?) then to try to change a static class into a multipleton(okay, so I'm making words up now).
Good luck. This stuff was mostly trial and error for me--figured it out like 5 years ago though, and I've never found an instance where I regretted not having static class/methods.
Helper / Utility methods are just fine. Don't worry about adding them to a library inside your application or Framework. Most frameworks that I have seen use them in many varieties.
That being said, if you want to get really crafty about them you should look into extension methods in C# 3.0. Using extension method will make your Utilities a little more of a "holistic" part of your framework which it seems like what you're trying to do by considering to make them abstract. Not to mention extension method are a lot of fun to write!

Categories