Public static methods - a bad sign? - java

I've just read this article here: http://hamletdarcy.blogspot.com/2008/04/10-best-idea-inspections-youre-not.html, and the last bit in particular got me thinking about my code, specifically the advice:
What in the world is a public method doing on your object that has no dependency on any fields within the object? This is certainly a code smell. The problem is that the "auto-fix" for the inspection is to apply the static keyword. Nooooo. That's not what you want to do. A public method without any dependency on object state can't possibly be part of an object that has one clearly stated charter. It's just not cohesive and should be placed somewhere else. So: if the method is private, accept the auto-fix, but if the method is public then don't.
The code in question is essentially an object transformer. It takes an object of type A and converts it to a different type.
My hierarchy is like this:
Interface ObjectTransformer -> GenericObjectTransformer
and then below this, GenericObjectTransformer is extended by ObjectTransformerA and ObjectTransformerB
Now, some functionality is required by both ObjectTransformerA and ObjectTransformerB, but doesnt actually depend on any instance variables of GenericObjectTransformer, so its a protected static method in GenericObjectTransformer.
Is this a violation of the rule above? Obviously this is protected rather than public, but its still a method accessible from outside of the class that has nothing to do with the class itself?
Any thoughts?

I disagree with the excerpt you pulled.
A public method without any dependency on object state can't possibly be part of an object that has one clearly stated charter. It's just not cohesive and should be placed somewhere else. So: if the method is private, accept the auto-fix, but if the method is public then don't.
Just because a method is static and has no relation to state, doesn't mean it falls under the "low cohesion" category. Cohesion/Functionality isn't based on state.
When you are trying to determine Cohesiveness think about the role of the class as a whole, not just the instance variables. If the logic you are looking at is related to the generic concept (GenericObjectTransformer) then leave it there.
If it is a routine to calculate the orbit of the moon, or the depth of the ocean move it to a utility class (another smelly area of our field).

It feels slightly unclean, but is seem preferable to the alternatives I can think of.
I think that the original
A public method without any dependency
on object state can't possibly be part
of an object that has one clearly
stated charter.
You reference is too black and white, and your situation is even greyer.
By having your protected method you are nicely documenting that its intended for use by derived classes. If you don't put it in the base class, then presumbly it's got to go in some ObjectTransformUtility class. Is that win? More artefacts, more places to look.
One thought: if your ObjectTransormer class undergoes significant change then how likely are you to need to change these utility methods. After all if their business is to work agains the object's interface then in fact their cohesion is quite high.

Related

Single instance with methods in java

I am wondering about programming decision - which I think is matter of style.
I need to have single instance of class which has only methods and no attributes.
To obtain that in java I have two options:
create an abstract class with static methods within, thus it will not be possible to create any instance of the class and that is fine,
use a singleton pattern with public methods.
I tend to go for second approach although met with 1. Which and why is better of those, or there is third option.
Would it make sense for that singleton to implement an interface, allowing you to mock out those methods for test purposes?
I know it goes against testing dogma these days, but in certain situations I think a static method is fine. If it's the kind of behaviour which you're never going to want to fake for test purposes, and which is never going to be polymorphic with other implementations, I don't see much point in making a singleton. (Singletons are also generally the enemy of testability, although if you only directly refer to them in the injection part of your code, they can implement appropriate interfaces so their singletoneity never becomes a problem.)
It's worth mentioning that C# has "static classes" for this kind of situation - not only do they prohibit other code from deriving from or instantiating the class, but you can't even use it as a parameter. Basically it signals the intent very clearly.
I would definitely suggest at least having a private constructor to prevent instantiation by the outside world.
My personal view is that the class should contain a private constructor and NOT be abstract. Abstract suggest to a reader that there is a concrete version of the class somewhere, and they may waste time searching for it. I would also make sure you comment your code effectively.
public class myClass {
/** This class should never be instantiated. */
private myClass() {
}
public static void myMethod() {
}
...
//etc
...
}
For option #1, it may not even be that important to restrict instantiation of your static utility class. Since all it has is static methods and no state, there is no point - but neither harm - instantiating it. Similarly, static methods can't be overridden so it does not make sense - nor difference - if it is subclassed.
If it had any state, though - or if there is a chance that it will get stateful one day - it may be better to implement it as a normal class. Still I would prefer not to use it as a Singleton, rather to pass its sole instance around via dependency injection. This makes unit testing so much easier in the long run.
If it holds a state I would use the singleton pattern with private constructors so you can only instantiate from within the class. If it does not hold a state, like the apache commons utility classes, I would use the static methods.
I've never seen the problem with static methods. You can think of static methods as somehow breaking OO, but they make perfect sense if you think of static as a marker that something is stateless. You find this in the java apis in places like java.Math. If you're worried about subclassing you can always make it final.
There is a danger in that a class like that can end up as a "utility method garbage can", but as long as the functionality doesn't diverge too much then there's nothing wrong with it.
It's also clearer, as there's no need to manage an object lifecycle like you would with a singleton (and since there's no state, what's the point of that anyway?).
For a single instance, I suggest you have an enum, with one instance.
However, for a class with no attributes, you don't have to have an instance. You can use a utility class. You can use an enum, with no instances and only static methods. Note: this cannot be easily mocked out.
You can still implement an interface if you ever need to mock out the implementation in testing.

Should Java methods be static by default?

Say you're writing method foo() in class A. foo doesn't ever access any of A's state. You know nothing else about what foo does, or how it behaves. It could do anything.
Should foo always be static, regardless of any other considerations? Why not?
It seems my classes are always accumulating many private helper methods, as I break tasks down and apply the only-write-it-once principle. Most of these don't rely on the object's state, but would never be useful outside of the class's own methods. Should they be static by default? Is it wrong to end up with a large number of internal static methods?
To answer the question on the title, in general, Java methods should not be static by default. Java is an object-oriented language.
However, what you talk about is a bit different. You talk specifically of helper methods.
In the case of helper methods that just take values as parameters and return a value, without accessing state, they should be static. Private and static. Let me emphasize it:
Helper methods that do not access state should be static.
1. Major advantage: the code is more expressive.
Making those methods static has at least a major advantage: you make it totally explicit in the code that the method does not need to know any instance state.
The code speaks for itself. Things become more obvious for other people that will read your code, and even for you in some point in the future.
2. Another advantage: the code can be simpler to reason about.
If you make sure the method does not depend on external or global state, then it is a pure function, ie, a function in the mathematical sense: for the same input, you can be certain to obtain always the same output.
3. Optimization advantages
If the method is static and is a pure function, then in some cases it could be memoized to obtain some performance gains (in change of using more memory).
4. Bytecode-level differences
At the bytecode level, if you declare the helper method as an instance method or as a static method, you obtain two completely different things.
To help make this section easier to understand, let's use an example:
public class App {
public static void main(String[] args) {
WithoutStaticMethods without = new WithoutStaticMethods();
without.setValue(1);
without.calculate();
WithStaticMethods with = new WithStaticMethods();
with.setValue(1);
with.calculate();
}
}
class WithoutStaticMethods {
private int value;
private int helper(int a, int b) {
return a * b + 1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int calculate() {
return helper(value, 2 * value);
}
}
class WithStaticMethods {
private int value;
private static int helper(int a, int b) {
return a * b + 1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int calculate() {
return helper(value, 2 * value);
}
}
The lines we are interested in are the calls to helper(...) on the classes WithoutStaticMethods and WithStaticMethods.
Without static methods
In the first case, without static methods, when you call the helper method the JVM needs to push the reference to the instance to pass it to invokespecial. Take a look at the code of the calculate() method:
0 aload_0
1 aload_0
2 getfield #2 <app/WithoutStaticMethods.value>
5 iconst_2
6 aload_0
7 getfield #2 <app/WithoutStaticMethods.value>
10 imul
11 invokespecial #3 <app/WithoutStaticMethods.helper>
14 ireturn
The instruction at 0 (or 1), aload_0, will load the reference to the instance on the stack, and it will be consumed later by invokespecial. This instruction will put that value as the first parameter of the helper(...) function, and it is never used, as we can see here:
0 iload_1
1 iload_2
2 imul
3 iconst_1
4 iadd
5 ireturn
See there's no iload_0? It has been loaded unnecessarily.
With static methods
Now, if you declare the helper method, static, then the calculate() method will look like:
0 aload_0
1 getfield #2 <app/WithStaticMethods.value>
4 iconst_2
5 aload_0
6 getfield #2 <app/WithStaticMethods.value>
9 imul
10 invokestatic #3 <app/WithStaticMethods.helper>
13 ireturn
The differences are:
there's one less aload_0 instruction
the helper method is now called with invokestatic
Well, the code of the helper function is also a little bit different: there's no this as the first parameter, so the parameters are actually at positions 0 and 1, as we can see here:
0 iload_0
1 iload_1
2 imul
3 iconst_1
4 iadd
5 ireturn
Conclusion
From the code design angle, it makes much more sense to declare the helper method static: the code speaks for itself, it contains more useful information. It states that it does not need instance state to work.
At the bytecode level, it is much more clear what is happening, and there's no useless code (that, although I believe the JIT has no way to optimize it, would not incur a significant performance cost).
If a method does not use instance data, then it should be static. If the function is public, this will give the important efficiency boost that you don't need to create a superfluous instance of the object just to call the function. Probably more important is the self-documentation advantage: by declaring the function static, you telegraph to the reader that this function does not use instance data.
I don't understand the sentiment of many posters here that's there's something wrong with having static functions in a Java program. If a function is logically static, make it static. The Java library has many static functions. The Math class is pretty much filled with static functions.
If I need, say, a function to calculate a square root, the rational way to do it would be:
public class MathUtils
{
public static float squareRoot(float x)
{
... calculate square root of parameter x ...
return root;
}
}
Sure, you could make a "more OOPy" version that looked like this:
public class MathUtils
{
private float x;
public MathUtils(float x)
{
this.x=x;
}
public float squareRoot()
{
... calculate square root of this.x ...
return root;
}
}
But aside from meeting some abstract goal of using OOP whenever possible, how would this be any better? It takes more lines of code and it's less flexible.
(And yes, I now there's a square root function in the standard Math class. I was just using this as a convenient example.)
If the only place a static function is used and is every likely to be used is from within a certain class, then yes, make it a member of that class. If it makes no sense to call it from outside the class, make it private.
If a static function is logically associated with a class, but might reasonably be called from outside, then make it a public static. Like, Java's parseInt function is in the Integer class because it has to do with integers, so that was a rational place to put it.
On the other hand, it often happens that you're writing a class and you realize that you need some static function, but the function is not really tied to this class. This is just the first time you happened to realize you need it, but it might quite rationally be used by other classes that have nothing to do with what you're doing now. Like, to go back to the square root example, if you had a "Place" class that included latitude and longitude, and you wanted a function to calculate the distance between two places and you needed a square root as part of the calculation, (and pretending there was no square root function available in the standard library), it would make a lot of sense to create a separate square root function rather than embedding this in your larger logic. But it wouldn't really belong in your Place class. This would be a time to create a separate class for "math utilities" or some such.
You ask, "Should foo always be static, regardless of any other considerations?" I'd say "Almost, but not quite."
The only reason I can think of to make it not static would be if a subclass wants to override it.
I can't think of any other reasons, but I wouldn't rule out the possibility. I'm reluctant to say "never ever under any circumstances" because someone can usually come up with some special case.
Interesting question. In practical terms, I don't see the point in making class A's private helper methods static (unless they're related to a publicly-accessible static method in A, of course). You're not gaining anything -- by definition, any method that might need them already has an instance of A at its disposal. And since they're behind-the-scenes helper methods, there's nothing to say you (or another co-worker) won't eventually decide one of those stateless helpers might actually benefit from knowing the state, which could lead to a bit of a refactoring nuisance.
I don't think it's wrong to to end up with a large number of internal static methods, but I don't see what benefit you derive from them, either. I say default to non-static unless you have a good reason not to.
No. Never. Static methods should be an exception. OO is all about having Objects with behaviour which revolves around the object's state. Imho, ideally, there shouldn't be any (or very few) static methods, because everything unrelated to the object's state could (and to avoid leading the concept of an object ad absurdum, should) be placed in a plain old function at module level. Possible exception for factories because Complex.fromCartesian (to take a wikipedia example) reads so well.
Of course this (edit: Module-level functions) isn't possible in a single-paradigm OO language (edit: like Java) - that's why I'm such a devoted advocate of multi-paradigm language design, by the way. But even in a language exclusively OO, most methods will revolve around the object's state and therefore be nonstatic. That is, unless your design has nothing to do with OO - but in this case, you're using the wrong language.
I usually
Perform these steps in order, as needed:
a) I write some code in a member method, figure out that I can probably re-use some of this code and
Extract to non-static method
b) Now I'll see if this method needs access to state or if I can fit its needs into one or two parameters and a return statement. If the latter is the case:
Make method (private) static
c) If I then find that I can use this code in other classes of the same package I'll
Make method public and move Method to a package helper class with default visibility
E.g. In package com.mycompany.foo.bar.phleeem I would create be a class PhleeemHelper or PhleeemUtils with default visibility.
d) If I then realize that I need this functionality all over my application, I
Move the helper class to a dedicated utility package
e.g. com.mycompany.foo.utils.PhleeemUtils
Generally I like the concept of least possible visibility. Those who don't need my method shouldn't see it. That's why I start with private access, move to package access and only make things public when they are in a dedicated package.
Unless you pass in an object reference, a static method on an class enforces that the method itself cannot mutate the object because it lacks access to this. In that regard, the static modifier provides information to the programmer about the intention of the method, that of being side-effect free.
The anti-static purists may wish to remove those into a utility class which the anti-utility purists surely object to. But in reality, what does artificially moving those methods away from their only call site achieve, other than tight coupling to the new utility class.
A problem with blindly extracting common utility methods into their own classes is those utilities should really be treated as a new public API, even if it's only consumed by the original code. Few developers, when performing the refactoring, fail to consider this. Fast-forward to other devs using the crappy utility class. Later on somebody makes changes to the extension to suit themselves. If you're lucky a test or two breaks, but probably not.
I generally don't make them static but probably should. It's valuable as a hint to tell the next coder that this method CANT modify the state of your object, and it's valuable to give you a warning when you modify the method to access a member that you are changing the nature of the method.
Coding is all about communicating with the next coder--don't worry about making the code run, that's trivial. So to maximize communication I'd say that if you really need such a helper, making it static is a great idea. Making it private is critical too unless you are making a Math. like class.
Java conflates the concepts of module, namespace, adt, and class, as such to claim that some class-oriented OO-purity should prevent you from using a java class as a module, namespace, or adt is ridiculous.
Yes the methods should be static. Purely internal support methods should be private; helper methods protected; and utility functions should be public. Also, there is a world of difference between a static field, a static constant, and a public static method. The first is just another word for 'global variable'; and is almost always to be avoided, even mediation by accessor methods barely limits the damage. The second is treating the java class as a namespace for a symbolic constant, perfectly acceptable. The third is treating the java class as a module for a function, as a general rule side-effects should be avoided, or if necessary, limited to any parameters passed to the function. The use of static will help ensure that you don't inadvertently break this by accessing the object's members.
The other situation you will find static methods invaluable is when you are writing functional code in java. At this point most of the rules-of-thumb developed by OO-proponents go out the window. You will find yourself with classes full of static methods, and public static function constants bound to anonymous inner functors.
Ultimately java has very weak scoping constructs, conflating numerous concepts under the same 'class' and 'interface' syntax. You shouldn't so much 'default' to static, as feel free to use the facilities java offers to provide namespaces, ADT's, modules, etc as and when you feel the need for them.
I find it difficult to subscribe to those avoid-static-methods theories. They are there to promote a completely sanitary object-oriented model anti-septically cleansed of any deviation from object relationships. I don't see any way essential to be anti-septically pure in the practice object-orientedness.
Anyway, all of java.util.Arrays class are static. Numeric classes Integer, Boolean, String have static methods. Lots of static methods. All the static methods in those classes either convert to or from their respective class instances.
Since good old Gosling, et al, proved to be such useful role models of having static methods - there is no point avoiding them. I realise there are people who are perplexed enough to vote down my response. There are reasons and habits why many programmers love to convert as much of their members to static.
I once worked in an establishment where the project leader wanted us to make methods static as much as possible and finalize them. On the other hand, I am not that extreme. Like relational database schema design, it all depends on your data modelling strategy.
There should be a consistent reason why methods are made static. It does not hurt to follow the standard Java library pattern of when methods are made static.
The utmost importance is programming productivity and quality. In an adaptive and agile development environment, it is not only adapting the granularity of the project to respond effectively to requirements variation, but also adapting programming atmosphere like providing a conformable coding model to make best use of the programming skill set you have. At the end of the day (a project almost never ends), you want team members to be efficient and effective, not whether they avoided static methods or not.
Therefore, devise a programming model, whether you want MVP, injection, aspect-driven, level of static-avoidance/affinity, etc and know why you want them - not because some theoretical nut told you that your programming practice would violate oo principles. Remember, if you work in an industry it's always quality and profitability not theoretical purity.
Finally what is object-oriented? Object-orientation and data normalization are strategies to create an orthogonal information perspective. For example, in earlier days, IBM manuals were written to be very orthogonal. That is, if a piece of info is written somewhere in a page within those thousands of manuals, they avoid repeating that info. That is bad because you would be reading learning how to perform a certain task and frequently encounter concepts mentioned in other manuals and you would have to be familiar with the "data model" of the manuals to hunt those connecting pieces of info thro the thousands of manuals.
For the same reason, OS/2 failed to compete with Microsoft because IBM's concept of orthogonality was purely machine and data based and IBM was so proudly declaring their true object-orientedness vs Microsoft's false object-orientedness pandering to human perspective. They had forgotten we humans have our own respective varying orthogonal perspectives of information that do not conform to data and machine based orthogonality or even to each other.
If you are familiar with the topology of trees, you would realise that you could pick any leaf node and make it the root. Or even any node, if you don't mind having a multi-trunk tree. Everyone thinks his/her node is the root when in fact any could be the root. If you think your perspective of object-orientation is the canon, think again. More important is to minimise the number of nodes that are accepted as candidate roots.
There needs to be a compromise between effectiveness and efficiency. There is no point in having an efficient data or object model that can be hardly effectively used by fellow programmers.
If it does nothing with objects of this class, but actually belong to this class (I would consider moving it elsewhere), yes it should be static.
Don't use static if you can avoid it. It clashes with inheritance ( overriding ).
Also, not asked but slightly related, don't make utility methods public.
As for the rest, I agree with Matt b. If you have a load of potentially static methods, which don't use state, just put them in a private class, or possibly protected or package protected class.
It depends i.g. java.lang.Math has no method which isn't static.
(You could do a static import to write cos() instead of Math.cos())
This shouldn't be overused but as some code that is intented to be called as a utility it would be acceptable. I.g Thread.currentThread()
A static method is used to identify a method (or variable for that matter) that does not have to do with the objects created from that class but the class itself. For instance, you need a variable to count the number of objects created. You would put something like: 'private static int instances = 0;' and then put something in the constructor for that class that increments 'instances' so you may keep count of it.
Do think hard before creating a static method, but there are times when they are a good solution.
Joshua Bloch in "Item 1: Consider Static Factory Methods Instead of Constructors" in Effective Java makes a very persuasive case that static methods can be very beneficial. He gives the java.util.Collections class's 32 static factory methods as an example.
In one case, I have a hierarchy of POJO classes whose instances can be automatically serialized into XML and JSON, then deserialized back into objects. I have static methods that use Java generics to do deserialization: fromXML(String xml) and fromJSON(String json). The type of POJO they return isn't known a priori, but is determined by the XML or JSON text. (I originally packaged these methods into a helper class, but it was semantically cleaner to move these static methods into the root POJO class.)
A couple of other examples:
Using a class as a namespace to group related methods (eg, java.lang.Math).
The method truly is a private class-specific helper method with no need to access instance variables (the case cited here). Just don't sneak a this-equivalent into its argument list!
But don't use statics unthinkingly or you run the danger of falling into a more disorganized and more procedural style of programming.
No, the use of statics should be quite niche.
In this case the OP is likely 'hiding' state in the parameters passed into the static method. The way the question is posed makes this non-obvious (foo() has no inputs or outputs), but I think in real world examples the things that should actually be part of the object's state would fall out quite quickly.
At the end of the day every call to obj.method(param) resolves to method(obj, param), but this goes on at a way lower level than we should be designing at.
If it's only ever used by methods in A and wouldn't have any use outside it, then it should be static (and, probably, be placed in a Helper Class. It doesn't have any use outside A now, but there's no guarantee it will never have. Otherwise, it shouldn't.
If it doesn't have anything to do with the state of A, it could be useful at other places...
Anyway, that doesn't make a good reason for Java methods to be static by default.
Talking about this last issue, they shouldn't be static by default, because having to write 'static' make people think before writing static methods. That's a good practice when you have heterogeneous teams (the ones where Java is most useful).
When you write a static method you should keep in mind that you'r gonna use it at use-site with static-import (make it look class free) and thus it should behave just like a function which doesn't something and may or may not return something and is isolated with the state of class it belongs to. So static methods should be a rare situation.
If you seem to be making a lot of helper methods, then consider using package-private instance methods instead of private ones. Less typing, less boilerplate since you can re-use them as a helper to other classes in the same package.
I think "private static" (edit: for methods) is kind of an oxymoron in Java. The main point of static methods in my mind is to provide access to functions outside of the context of object instances. In other words, they're practically only ever useful if they're public. If you're only calling a method from within the context of a single object instance, and that method is private, it makes no sense to make it static. (edit: but, it makes no practical difference).
In this sort of case, I usually try to make the methods abstract enough that they're useful in other contexts, and I make them public in a utility class. Look at it as writing supporting library code, and think hard about your api.
Most static methods are written because
You break down a complex method into submethods, or
You wish String (or Date, or...) had some functionality that it doesn't have
The first is not bad per se, but it's often a sign that you're missing objects. Instead of working with default types such as String or List, try inventing your own classes and move the static methods to those classes.
The second reason produces the always-popular StringUtil, DateUtil, FooUtil classes. These are problematic because you have no way to discover that they exist, so programmers often write duplicates of these utility methods. The solution, again, is to avoid using String and Date all the time. Start creating your own objects, perhaps by wrapping the original object. The static methods become non-static methods of the new object.
If foo() doesn't have anything to do with Object A then why is the method in there?
Static methods should still be relevant. If there isn't anything going on then why have you written a method that has no association with it?
If foo is private, it may be anything, static or not. But, most of the time it will be not static as these is one less word to type. Then, if you need to use the state because you've changed your code, you can do it right away.
When it is protected or public, it depends on what it does. A rule of thumb is to make it not static when it isn't a part of the instance's behaviour, and make it static when it makes sense to call it without any object.
If you are unsure, ask yourself if it makes sense to override the method in a subclass.
I think letting the methods in Java to be static will result in a rather chaotic implementation by beginner who haven't understand OO correctly. We've been there and think about it. If the methods were static as default how hard it is for us to understand the OO principle?
So yes, once you mastered the concept, it is a bit itchy to have static all over the methods (as result of refactoring). Nothing we ca do about that I think.
NB: Let me guess, are you by any chance have read Clean Code?
Plenty of interesting answers.
If you desperately seek a rule, then use this:
If the code is only ever used by instance methods of a single class, then make it an instance method - it is simply an extraction of code out of an instance context - which could be refactored back into (or out of) methods that access instance state.
If the code is used by MORE THAN ONE class, and contains no access to instance variables in the class in which the method resides, then make it static.
End of story.

Java protected fields vs public getters

What is better practise and why: accessing base class variables through a protected field or a public getter on the private field.
(The getter will be public regardless)
If there's going to be a public getter anyway, why would you want to expose the field itself more widely than absolutely necessary? That means it's immediately writable by subclasses (unless it's final to start with).
Personally I like all my fields to be private: it provides a cleaner separation between API and implementation. I regard the relationship between a superclass and a subclass as similar to that of a caller and callee - changes to the underlying implementation shouldn't break subclasses any more than they should break callers. The name of a field is an implementation detail which shouldn't impact other classes.
Admittedly my view is occasionally seen as somewhat extreme...
You should always program against the public API of a class, that is, use the public methods.
The reason is simple. Someday in the future, you or someone else might want to change the implementation. This should always be possible. If you rely on instance variable, you limit yourself.
Also, when accessing the variable, you can not control if that variable is read-only nor can you add checks when this variable is changed.
If you use setters/getters, you can allways add validation, checking etc later on. You can also only provide a getter to make a variable read only.
Direct field access is not preferred. Use public or protected setters and getters.
The getter need not be public - if you wan to hide the data from "outsiders", but give the data to subclasses, use protected
Some of Sun's recommendations on controlling access to fields are here. Note that making a field protected exposes it to the package as well, not only to subclasses. Generally, as stated at the link above, fields should be private unless there is a very good reason not to do so.
Effective Java 2nd Edition says
Item 13: Minimize the accessibility of classes and members
The rule of thumb is simple: make each class or member as inaccessible as
possible. In other words, use the lowest possible access level consistent with the
proper functioning of the software that you are writing.
So if you are not sure why you need a protected class member (ie you don't need the field to be accessible to subclasses or classes in the same package), then declare it private. If you wish to set it from outside the class, then make a public setter.
However, if your member is final, then making it protected might be ok in some cases (ie it doesn't reveal sensitive information).
One potential security issue I would like to mention is that if you have an array declared protected final (even public final), the array reference is final (cannot be modified), but the objects held in the array are not final (an intruder could change the array contents).
If you know c++, you probably know that
const int * someMember
is different from
int * const someMember
The latter is like the final array in java.
The fix for the aforementioned security hole is to return a deep copy of the array or return it as a read only list.
Generally, you should use Sun's recommendations. There is one big exception: if you're programming for Android.
The reason is performance. With every virtual method invocation, there is overhead involved in using the lookup table to route the method to its object. This overhead is not involved when accessing a local variable.
Here are some links that explain this in a little more depth:
http://developer.android.com/training/articles/perf-tips.html#GettersSetters
http://blog.leocad.io/why-you-shouldnt-use-getters-and-setters-on-android/
It's important to know what you're trying to accomplish:
The field's value should be accessible to client code, using a public interface.
The field is meant to be used by subclasses.
In plain ol' Java, getters and setters accomplish both tasks. But Android is different. If you're doing #1, then you should use public getters and setters. If you're doing #2, then you should use protected fields. If you're doing both, use both.
I would like to present you with some arguments protecting "protected" fields in Java:
"You may favor accessing base class members using protected fields over public accessors in situation where you need to avoid value validation".
However if this is not the case, then private fields with public accessors should be used, to compliment hermetization.
The principle of getters and setters is to provide validation to the values inputted and outputted to the class member. However, in OOP languages, we operate on objects not classes. Base class and specialized class represent a single object, that is why it is perfectly fine to access specific class members over protected field.
Consider the following abstract example with a car:
- you have a base class Car and the derived class Porshe.
- Car class may have field like engine, which value is not set in Cars constructor (maybe the type of engine is known only after object initialization)
- You create a Porshe class object that contains some logic used to calculate engine type using some external data.
In this example, it is expected that engine field has a public getter, so car users know what engine the car has. However, there is no public setter as we expect car drivers not to temper with the engine! That is why, it is perfectly fine to make engine a protected field, so the Porshe class can set its value at some time in future.
Yes, some people will probably say "then use protected setter!".
And I will repeat: in OOP languages we work with objects not classes.
Single responsibility principle - yes, but as object not as class.
If you say: "at some point if we use protected fields over 3 or 5 inheritance levels, it may be troublesome to understand what happens to the field if each class performs some operation with it". And then I answer: That is another antipattern - your object is probably too big at this point and voids Single Responsibility principle.
Accessing protected fields from a subclass is one of the ways that inheritance violates encapsulation. Using the public API is better for this reason.

Java abstract static Workaround

I understand that neither a abstract class nor an interface can contain a method that is both abstract and static because of ambiguity problems, but is there a workaround?
I want to have either an abstract class or an interface that mandates the inclusion of a static method in all of the classes that extend/implement this class/interface. Is there a way to do this in Java? If not, this may be my final straw with Java...
EDIT 1: The context of this problem is that I have a bunch of classes, call them Stick, Ball, and Toy for now, that have a bunch of entries in a database. I want to create a superclass/interface called Fetchable that requires a static method getFetchables() in each of the classes below it. The reason the methods in Stick, Ball, and Toy have to be static is because they will be talking to a database to retrieve all of the entries in the database for each class.
EDIT 2: To those who say you cannot do this in any language, that is not true. You can certainly do this in Ruby where class methods are inherited. This is not a case of someone not getting OO, this is a case of missing functionality in the Java language. You can try to argue that you should never need to inherit static (class) methods, but that is utterly wrong and I will ignore any answers that make such points.
You have a couple of options:
Use reflection to see if the method exists and then call it.
Create an annotation for the static method named something like #GetAllWidgetsMethod.
As others have said, try to not use a static method.
There are lots of answers about 'this does'nt make sense..' but indeed I met a similar problem just yesterday.
I wanted to use inheritance with my unit tests. I have an API and several its implementations. So I need only 1 set of unit tests for all implementations but with different setUp methods which are static.
Workaround: all tests are abstract classes, with some static fields with protected access modifier. In all implementations I added static methods which set these static fields. It works rather nice, and I avoided copy and paste.
I too am dealing with this problem. For those that insist that it "doesn't make sense", I would invite you to think outside of that semantic box for a moment. The program I am working with is inherently about reflection.
Reflection, as you know, can take three orders of magnitude longer than straight-up binary function calling. That is an inevitable problem, and the software needs to port to as many machines as possible, some of which will be 32 bit and slower than my development machine to begin with. Thus, the applicability of a class to the requested operation needs to be checked via a static method, and all of the reflective methods are run at once during module booting.
Everything works, first and foremost. I've built the entire thing. The only catch is that a module can be compiled in a .class without compile time checking to see if the identifying static function exists at all, resulting in an innately useless class. Without the identifier, and its included information, for security's sake the module is not loaded.
I clearly understand the issue with the complete definition of "abstract" and "static", and understand that they don't make sense together. However, the ability to have a class method that is compiler-enforced for inclusion is lacking in Java, and as much as I like the language, I miss it. Thus, this is a human constraint on every programmer that ever works on the software, which I'm sure we can all agree is a pain.
There's a lot of 'this makes no sense' or 'this can't be because' and 'why do you want it?' (or worse: 'you don't have to want it!') in all those answers. However, these answers also indirectly give reasons why it should be possible.
It must be differentiated between the concept and the implementation.
Sure, overriding a static method makes no sense. And it also isn't what the question was about.
It was asked for a way to force implementation of a certain static method (or constant or whatever) in every derived class of an abstract class. Why this is required it the matter of the one who wants to write an appllication with Jave, and no business of anyone else.
This has nothing to do with how the compiler compiles the method and how it is done at runtime.
Why shoudl it be possible? because there are things that are class specific (and not instance specific) and therefore should be static, while they NEED to be impleented in every single subclass (or class that implements an interface).
Let's say there is an abstract class 'Being'. Now there are subclasses like 'animals' and 'plants'.
Now there are only mammals and fishes allowed for animals. This information is specific to the animals class, not to any instance nor doe sit belong to any superclass or subclass. However, this information must be provided by teh class, not an instance, because it is required to properly construct an animal instance. So it MUST be there and it CANNOT be in the instance.
In fact, Java has such a thing- Every object has a class specific field 'class'. It is class-specific, not inherited, no override and it must be there. Well the compiler creates it implicitly, but obviously the compiler CAN do it. So why not allowing this for own fields too.
After all, it is just a matter of definition how the combination 'abstract static' is interpreted when the compiler checks the intheritance chain for abstract functions.
Nobody was ever demanding that there should be an inheritance of the superclass class functions (which could still make some sense, depending on what this function actually does - after all classes inherit static functions of their superclasses, even though you might get a warning that you should access it directly when you call it by the subclass))
But to summarize: the Java language offers no way to do it at compile time while there is no reason (othe rthan plain dogmatic) to not doing so.
The only way is to write a static final function to the abstract class that tries to find the static function/field of the subclass when it is loaded (or loads all existing subclasses and checks them). If properly made, it gives a runtime error on first use. Complex and dirty but better than nothing. At least it prevents bugs where you get the information from the wrong superclass.
It won't work for interfaces, though.
A type system allows you to express some constraints among types, but it's limited. That's why javadocs are littered with constraints in human language, asking people to follow rules that the compiler cannot check.
if you want to extend it beyond what language provides natively, you can write your own static analysis tool. that is not uncommon. for example: findbug. also IDEs do that too, they checking thing beyond what language dictates. you can write a plug in to enforce that a subclass must have a static method of such signature.
in your case, it's not worth it. have javadoc in the superclass urge implementors to include a static method, that's good enough.
I'll provide a convoluted way of expressing your constraint anyway, but DO NO DO IT. people get really carried away of make everything checkable at compile time, at the price of making code unreadable.
interface WidgetEnumerator
{
List getAllWidgets();
}
public class Abs<T extends WidgetEnumerator>
{
static List getAllWidgets(Class<? extends Abs> clazz){ ... }
}
public class Sub extends Abs<SubWidgetEnumerator>
{
}
public class SubWidgetEnumerator implements WidgetEnumerator
{
public List getAllWidgets() { ... }
}
How it works: for any subclass of Abs, it is forced to provide an implementation of WidgetEnumerator. subclass author cannot forget that. Now invocation Abs.getAllWidgets(Sub.class) contains sufficient information to resolve that implementation, i.e. SubWidgetEnumerator. It is done through reflection, but it is type safe, there are no string literals involved.
I think I can give you a better answer after seeing your edits--your best bet is probably a factory pattern. (Not lovely, but better than singleton).
abstract class Widget
public static Widget[] getAllWidgetsOfType(Class widgetType) {
if(widgetType instanceof ...)
}
class Ball extends Widget
class Stick extends Widget
class Toy extends Widget
This is not a very good way to do it, but it's typical. Hibernate is the tool you would normally use to solve this problem, this is exactly what it's designed for.
The big problem is that it requires editing the base class whenever you add a new class of a given type. This can't be gotten around without reflection. If you want to use reflection, then you can implement it this way (Psuedocode, I'm not going to look up the exact syntax for the reflection, but it's not much more complex than this):
public static Widget[] getAllWidgetsOfType(Class widgetType) {
Method staticMethod=widgetType.getStaticMethod("getAllInstances");
return staticMethod.invoke();
}
This would give the solution you were asking for (to be bothered by the need to modify the base class each time you add a child class is a good instinct).
You could also make it an instance method instead of a static. It's not necessary, but you could then prototype the method (abstract) in Widget.
Again, all this is unnecessary and sloppy compared to Hibernate...
Edit: If you passed in a live "Empty" instance of a ball, stick or toy instead of it's "Class" object, you could then just call an inherited method and not use reflection at all. This would also work but you have to expand the definition of a Widget to include an "Empty" instance used as a key.
Static methods are relevant to an entire class of object, not the individual instances. Allowing a static method to be overridden breaks this dictum.
The first thing I would consider is to access your database from a non-static context. This is actually the norm for Java apps.
If you absolutely must use a static method, then have it parameterised with instance specific arguments (of a generic type) to allow the different subclasses to interact with it. Then call that single static method from you polymorphic methods.
No. You can't do that. If you're willing to compromise and make the method non-static or provide an implementation of the static method in your abstract class, you'll be able to code this in Java.
Is there a way to do this in Java?
I don't think there is a way to do this in any language. There's no point to it, since static methods belong to a class and can't be called polymorphically. And enabling polymorphic calls is the only reason for interfaces and abstract classes to exist.
Create a context interface containing your method with a name that matches your problem domain. (Name it "World" if you absolutely have to, but most of the time there's a better name)
Pass around implementation instances of the context object.
Ok, maybe my question was poorly asked, it seems like most of you didn't get what I was trying to do. Nonetheless, I have a solution that is somewhat satisfactory.
In the abstract super class, I am going to have a static method getAllWidgets(Class type). In it I'll check the class you passed it and do the correct fetching based on that. Generally I like to avoid passing around classes and using switches on stuff like this, but I'll make an exception here.
static methods can't be abstract because they aren't virtual. Therefore anywhere that calls them has to have the concrete type with the implementation. If you want to enforce that all implementations of an interface have a certain static method, then that suggests a unit test is required.
abstract class A
{
public static void foo()
{
java.lang.System.out.println("A::foo");
}
public void bar()
{
java.lang.System.out.println("A::bar");
}
}
class B extends A
{
public static void foo()
{
java.lang.System.out.println("B::foo");
}
public void bar()
{
java.lang.System.out.println("B::bar");
}
}
public class Main
{
public static void main(String[] args)
{
B b = new B();
b.foo();
b.bar();
A a = b;
a.foo();
a.bar();
}
}
For what it is worth I know exactly what you are trying to do.
I found this article while searching for the reasons I can't do it either.
In my case I have HUNDREDS of classes that inherit from a central base base and I want simply to get a reference like this:
ValueImSearchingFor visf = StaticClass.someArbitraryValue()
I do NOT want to write/maintain someArbitraryValue() for each and every one of hundreds of the inherited classes -- I just want to write logic once and have it calc a Unique Class-Sepcific value for each and every future written class WITHOUT touching the base class.
Yes I completely get OO - I've been writing Java for about as long as it's been available.
These specific classes are more like "Definitions" as opposed to actual Objects and I don't want to instantiate one every time I just need to see what someArbitraryValue() actually is.
Think of it as a PUBLIC STATIC FINAL that allows you to run a Method ONCE to set it initially. (Kinda like you can do when you define an Enum actually...)
I'd make a WidgetCollection class with an abstract Widget inner class.
You can extend the WidgetCollection.Widget class for each of your types of Widget.
No static methods necessary.
Example (not compiled or tested):
class WidgetCollection<W extends Widget> {
Set<W> widgets = new HashSet<W>();
Set<W> getAll() {
return widgets;
}
abstract class Widget {
Widget() {
widgets.add(this);
}
abstract String getName();
}
public static void main(String[] args) {
WidgetCollection<AWidget> aWidgets = new WidgetCollection<AWidget>();
a.new AWidget();
Set<AWidget> widgets = aWidgets.getAll();
}
}
class AWidget extends Widget {
String getName() {
return "AWidget";
}
}
It doesn't make sense to do what you're asking:
Why can't static methods be abstract in Java

Is there a rule of thumb for when to code a static method vs an instance method?

I'm learning Java (and OOP) and although it might irrelevant for where I'm at right now, I was wondering if SO could share some common pitfalls or good design practices.
One important thing to remember is that static methods cannot be overridden by a subclass. References to a static method in your code essentially tie it to that implementation. When using instance methods, behavior can be varied based on the type of the instance. You can take advantage of polymorphism. Static methods are more suited to utilitarian types of operations where the behavior is set in stone. Things like base 64 encoding or calculating a checksum for instance.
I don't think any of the answers get to the heart of the OO reason of when to choose one or the other. Sure, use an instance method when you need to deal with instance members, but you could make all of your members public and then code a static method that takes in an instance of the class as an argument. Hello C.
You need to think about the messages the object you are designing responds to. Those will always be your instance methods. If you think about your objects this way, you'll almost never have static methods. Static members are ok in certain circumstances.
Notable exceptions that come to mind are the Factory Method and Singleton (use sparingly) patterns. Exercise caution when you are tempted to write a "helper" class, for from there, it is a slippery slope into procedural programming.
If the implementation of a method can be expressed completely in terms of the public interface (without downcasting) of your class, then it may be a good candidate for a static "utility" method. This allows you to maintain a minimal interface while still providing the convenience methods that clients of the code may use a lot. As Scott Meyers explains, this approach encourages encapsulation by minimizing the amount of code impacted by a change to the internal implementation of a class. Here's another interesting article by Herb Sutter picking apart std::basic_string deciding what methods should be members and what shouldn't.
In a language like Java or C++, I'll admit that the static methods make the code less elegant so there's still a tradeoff. In C#, extension methods can give you the best of both worlds.
If the operation will need to be overridden by a sub-class for some reason, then of course it must be an instance method in which case you'll need to think about all the factors that go into designing a class for inheritance.
My rule of thumb is: if the method performs anything related to a specific instance of a class, regardless of whether it needs to use class instance variables. If you can consider a situation where you might need to use a certain method without necessarily referring to an instance of the class, then the method should definitely be static (class). If this method also happens to need to make use of instance variables in certain cases, then it is probably best to create a separate instance method that calls the static method and passes the instance variables. Performance-wise I believe there is negligible difference (at least in .NET, though I would imagine it would be very similar for Java).
If you keep state ( a value ) of an object and the method is used to access, or modify the state then you should use an instance method.
Even if the method does not alter the state ( an utility function ) I would recommend you to use an instance method. Mostly because this way you can have a subclass that perform a different action.
For the rest you could use an static method.
:)
This thread looks relevant: Method can be made static, but should it? The difference's between C# and Java won't impact its relevance (I think).
Your default choice should be an instance method.
If it uses an instance variable it must be an instance method.
If not, it's up to you, but if you find yourself with a lot of static methods and/or static non-final variables, you probably want to extract all the static stuff into a new class instance. (A bunch of static methods and members is a singleton, but a really annoying one, having a real singleton object would be better--a regular object that there happens to be one of, the best!).
Basically, the rule of thumb is if it uses any data specific to the object, instance. So Math.max is static but BigInteger.bitCount() is instance. It obviously gets more complicated as your domain model does, and there are border-line cases, but the general idea is simple.
I would use an instance method by default. The advantage is that behavior can be overridden in a subclass or if you are coding against interfaces, an alternative implementation of the collaborator can be used. This is really useful for flexibility in testing code.
Static references are baked into your implementation and can't change. I find static useful for short utility methods. If the contents of your static method are very large, you may want to think about breaking responsibility into one or more separate objects and letting those collaborate with the client code as object instances.
IMHO, if you can make it a static method (without having to change it structure) then make it a static method. It is faster, and simpler.
If you know you will want to override the method, I suggest you write a unit test where you actually do this and so it is no longer appropriate to make it static. If that sounds like too much hard work, then don't make it an instance method.
Generally, You shouldn't add functionality as soon as you imagine a use one day (that way madness lies), you should only add functionality you know you actually need.
For a longer explanation...
http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It
http://c2.com/xp/YouArentGonnaNeedIt.html
the issue with static methods is that you are breaking one of the core Object Oriented principles as you are coupled to an implementation. You want to support the open close principle and have your class implement an interface that describes the dependency (in a behavioral abstract sense) and then have your classes depend on that innterface. Much easier to extend after that point going forward . ..
My static methods are always one of the following:
Private "helper" methods that evaluate a formula useful only to that class.
Factory methods (Foo.getInstance() etc.)
In a "utility" class that is final, has a private constructor and contains nothing other than public static methods (e.g. com.google.common.collect.Maps)
I will not make a method static just because it does not refer to any instance variables.

Categories

Resources