Java Forum / General / November 2007
To static or not to static
Wojtek - 26 Oct 2007 18:37 GMT If I have a class such as: ------------------ public class MyClass { public MyClass() { super(); }
public void printThis(String parm) { System.out.println(parm); } } ------------------
I can run the method like this:
(new MyClass()).printThis("Hello World");
Since printThis only uses passed parameters, I could also have this: ------------------ public class MyClass { public MyClass() { super(); }
public static void printThis(String parm) { System.out.println(parm); } } ------------------ and then I can run the method like this:
MyClass.printThis("Hello World");
Both ways are valid, and functionally equivalent. The main difference being that the first way instantiates a class whereas the second does not.
Thoughts?
 Signature Wojtek :-)
Robert Klemme - 26 Oct 2007 19:01 GMT > If I have a class such as: > ------------------ [quoted text clipped - 39 lines] > > Thoughts? static!
robert
Lew - 26 Oct 2007 19:46 GMT Wojtek wrote:
>> If I have a class such as: >> ------------------ [quoted text clipped - 38 lines] >> being that the first way instantiates a class whereas the second does >> not.
> static! It depends!
The example presented does call for static, because there are no thread safety issues (that I can see), the parameters completely define the data involved and there is no link whatsoever to any instance information. This reasoning applies to methods; static variables are a whole lot more troublesome.
Many times I face this choice there is an argument to prefer instance implementations. It has to do with whether the instance holds state that is relevant to the method, such as resource handles. It's more object-oriented to define an object that holds such state than to pass the state separately as a parameter.
A compromise situation occurs where the static method applies a default operation on an instance of the same class, such as to provide a connection string or other lookup of a control parameter. The instance has the option to use its own version of that lookup, or to use the static default method.
Factory methods, of course, are often static, particularly in the idiom where the factory method creates instances of its own class.
 Signature Lew
Are Nybakk - 26 Oct 2007 19:38 GMT > If I have a class such as: > ------------------ [quoted text clipped - 39 lines] > > Thoughts? Well.. I havn't really used much static methods/fields myself, but they can be accessed accross packages. You might not always want that? Anyway, such a method as you show here should perhaps be in it's own class (like the methods in the java.lang.Math class).
Lew - 26 Oct 2007 19:48 GMT >> If I have a class such as: >> ------------------ [quoted text clipped - 43 lines] > Well.. I havn't really used much static methods/fields myself, but they > can be accessed accross packages. You might not always want that? That has to do with access specification: private, package-private (no modifier), protected or public. Static or not doesn't affect package visibility.
> Anyway, such a method as you show here should perhaps be in it's [sic] own > class (like the methods in the java.lang.Math class). In this case, they were. They were in their own class, "MyClass".
 Signature Lew
Are Nybakk - 27 Oct 2007 19:39 GMT >>> If I have a class such as: >>> ------------------ [quoted text clipped - 47 lines] > modifier), protected or public. Static or not doesn't affect package > visibility. Thanks for correcting me :)
>> Anyway, such a method as you show here should perhaps be in it's [sic] >> own class (like the methods in the java.lang.Math class). > > In this case, they were. They were in their own class, "MyClass". Depending on what the class contains - as Arne pointed out.
Daniel Pitts - 26 Oct 2007 20:11 GMT > If I have a class such as: > ------------------ [quoted text clipped - 39 lines] > > Thoughts? It depends, can printThis get overridden by subclasses?
If you ONLY ever do new MyClass().printThis("something"), then likely it should be static. At the same time, it would be more flexible to have an instance that can have different behaviors depending on how it was constructed/which class it really is/configuration.
Generally, if you would make the method final, and it doesn't depend on the state of the object, you should consider making it static.
 Signature Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
Mark Space - 27 Oct 2007 02:26 GMT > Thoughts? Honestly? I thought your example was stupid.
Really, if all you want to do is print a string, why declare a class at all? System.out.println("Hello World"); does the same thing as your example.
Give us an example with some meat on it.
Andrew Thompson - 27 Oct 2007 02:55 GMT >> Thoughts? > >Honestly? I thought your example was stupid. I 'agree'. So long as we can change the word 'stupid' for the phrase 'less than optimal for demonstrating the point'.
The particular thing that caught my eye was the name of the method - 'printThis'. The 'This' implies to me 'the instance of the object' - hardly a candidate for 'static'!
>Really, if all you want to do is print a string, why declare a class at >all? System.out.println("Hello World"); does the same thing as your >example. > >Give us an example with some meat on it. I generally abhor abstractions in questions, for the same reason I abhor code snippets.
If the OP knows the answer, they might have a good chance of covering the salient points in snippets or abstractions, but then, if they know the answer, why are they asking us?
(Or to put that a less obtuse way. "When asking questions, avoid both snippets and abstractions.")
 Signature Andrew Thompson http://www.athompson.info/andrew/
Mark Space - 27 Oct 2007 08:56 GMT >>> Thoughts? >> Honestly? I thought your example was stupid. > > I 'agree'. So long as we can change the word 'stupid' for > the phrase 'less than optimal for demonstrating the point'. Fair enough. My reply was a little abrupt, and I hope it wasn't taken as a personal comment.
> If the OP knows the answer, they might have a good > chance of covering the salient points in snippets or > abstractions, but then, if they know the answer, why > are they asking us? I think he could have supplied more information about what he was actually trying to do. As is, the question struck me as far to general, and simple, to be of any practical value for discussion.
Given what he posted, I think my reply that neither method is preferred is correct. Don't reinvent the wheel, use the standard objects whenever possible. I'd say the same thing if he was asking about String or character manipulation, or logging error messages. Don't reinvent the wheel, use what's provided. Laziness is a virtue.
If he'd said instead, "I saw some code that did this, and I was wondering about it" there might be enough there to give him a fair answer.
Wojtek - 29 Oct 2007 16:26 GMT Andrew Thompson wrote :
>>> Thoughts? >> >> Honestly? I thought your example was stupid. > > I 'agree'. So long as we can change the word 'stupid' for > the phrase 'less than optimal for demonstrating the point'. Well the question was about which methodology to use where a method entirely uses passed parameters.
So I posted an SSCCE which was sufficient to illustrate the issue.
So next time I should post 100-200 lines of code from a real working class which happens to have one method which illustrates the issue?
 Signature Wojtek :-)
Lew - 29 Oct 2007 17:21 GMT > So I posted an SSCCE which was sufficient to illustrate the issue. The example was perfect for the intended purpose, and illustrated the question perfectly as well. I disagree that it should have been longer.
OTOH, the factors that distinguish the choice of static or not tend to emerge only in somewhat more complex circumstances. It is not didactically necessary to provide new SSCCEs for those circumstances; it suffices to outline the differences from the original example and how they would influence the decision.
For example, a class dedicated entirely to methods that receive all relevant state from method arguments would and should declare those methods static. A class that wishes a method to be overridable, that is, to display variant behavior polymorphically, must declare such a method at instance level even if all state arrives in the arguments. Such a class will also be intended for instantiation.
Factory methods for the class in which the factory appears should be static. (Factory classes with instance methods are a different idiom.)
Absent those rules of thumb, a class intended to be instantiable might prefer instance methods to static methods, if only to reduce the need for two ways to invoke methods in the code:
Foo foo = new Foo(). Baz zesult = Foo.act(); // act depends on no instance variables Bar result = foo.transform( zesult );
vs.
Foo foo = new Foo(). Baz zesult = foo.act(); // act depends on no instance variables Bar result = foo.transform( zesult );
For me at least, the presence of an instance variable makes it natural for that instance to own all the behaviors, even ones that might be implementable at class level. Even then, some behaviors so clearly belong to the class as such that it just makes sense to make them static.
 Signature Lew
Wojtek - 29 Oct 2007 17:34 GMT Lew wrote :
> For me at least, the presence of an instance variable makes it natural for > that instance to own all the behaviors, even ones that might be implementable > at class level. Even then, some behaviors so clearly belong to the class as > such that it just makes sense to make them static. I think so too.
Besides which, if a method is accessed in a static way, then it sort of indicates that the method is "standalone" to maintenance programmer.
I say sort of, because the method might still access static class properties.
 Signature Wojtek :-)
Mark Space - 30 Oct 2007 03:27 GMT > Well the question was about which methodology to use where a method > entirely uses passed parameters. [quoted text clipped - 3 lines] > So next time I should post 100-200 lines of code from a real working > class which happens to have one method which illustrates the issue? I'm sorry I called you example dumb, and I hope you didn't take any real offense. I just found your example entirely too brief to give me an idea what you were really asking.
But without some context, it's so hard to fix on just one element. Rather than a long SCCE, you could have posted a question about the use of statics in the Java API. That's large, and some people here might actually know why certain methods are encapsulated where they are.
Like, why does both javax.swing.SwingUtilities and java.awt.EvenQueue have the same (static) invokeLater() method? Kind of an interesting bit of history there....
Wojtek - 31 Oct 2007 17:00 GMT Mark Space wrote :
>> So I posted an SSCCE which was sufficient to illustrate the issue.
> I just found your example entirely too brief to give me an idea > what you were really asking. Well I tried to make it succinct. The method name could have been better, and what it did was trivial, but I cannot see what other code I could have added to "improve" the example.
Now that you have read the other posts, what would YOU create as an example?
> Like, why does both javax.swing.SwingUtilities and java.awt.EvenQueue have > the same (static) invokeLater() method? Yes, but I do Web development not Swing, so I am not familiar with that entire library. Moreover this is something which I am creating within my project, not external code.
> Kind of an interesting bit of history there.... Ok, do tell.
 Signature Wojtek :-)
Mark Space - 01 Nov 2007 01:04 GMT > Now that you have read the other posts, what would YOU create as an > example? I occasionally bump into things that don't make sense. Nothing springs to mind right away though.
I suppose the String class might be good for an example. It has a ton of constructors, a bunch of class methods, but also several static factories too.
So why not have specialized types of strings instead of all those constructors? Like the InputStream and OutputStream classes do it.
Is it better to have all those static constructors in the base String class, or should they have gone into a StringUtilities class?
Stuff like that. I can guess at some answers, but if there are hard reasons it would be interesting to know them.
> Mark Space wrote : >> Like, why does both javax.swing.SwingUtilities and java.awt.EvenQueue [quoted text clipped - 3 lines] > entire library. Moreover this is something which I am creating within my > project, not external code. Many folks speak Servlets here too. Pick an example from that API.
>> Kind of an interesting bit of history there.... As I understand it, SwingUtilities was intended as a temporary measure. The main utilities where always in awt.EventQueue. I always assumed that SwingUtilities were to be used with the javax.swing package and java.awt might go away at some point, but apparently that's not the case.
John W. Kennedy - 01 Nov 2007 01:41 GMT > I suppose the String class might be good for an example. It has a ton > of constructors, a bunch of class methods, but also several static > factories too.
> So why not have specialized types of strings instead of all those > constructors? Like the InputStream and OutputStream classes do it. Because the ...Stream classes all do different things, while all Strings, once constructed, are alike.
 Signature John W. Kennedy If Bill Gates believes in "intelligent design", why can't he apply it to Windows?
Arne Vajhøj - 27 Oct 2007 02:38 GMT > If I have a class such as: > ------------------ [quoted text clipped - 37 lines] > Both ways are valid, and functionally equivalent. The main difference > being that the first way instantiates a class whereas the second does not. You choose static or non-static based in what best fits with what you are doing.
Is MyClass a utility class or does it really model some type in your problem domain.
It is very easy to come up with good cases for static in 100 lines of code.
It is more rare to see such cases in 100000 lines of code.
But they do exist - there are some GoF patterns that indeed use static.
Arne
Adam Maass - 31 Oct 2007 08:35 GMT > If I have a class such as: > ------------------ [quoted text clipped - 39 lines] > > Thoughts? Generally speaking, if it's a method that does not depend on instance state, make it static. It's one way to reduce the scope of a method.
Lew - 31 Oct 2007 14:32 GMT > Generally speaking, if it's a method that does not depend on instance > state, make it static. It's one way to reduce the scope of a method. I do not understand the connection to scope. What I think of as "scope" is wider for a static method - it applies to every instance, not just the one for an instance method.
It's also not what I consider the criterion. Ownership is. If a behavior belongs to the class, the implementing method should be static. If an instance is extant, it's because the instance owns the behaviors of interest; in that case even methods that don't depend on instance state should be non-static. This lets the client see all behaviors as owned by the instance.
The need for polymorphism requires a non-static implementation, even if instance state doesn't affect the algorithm.
I also prefer instance methods to static methods. Unless a behavior clearly and unequivocally belongs to the class, I'll make it an instance method. I do that to reduce scope of the method, as I understand the concept of "scope".
 Signature Lew
Daniel Pitts - 31 Oct 2007 17:55 GMT >> Generally speaking, if it's a method that does not depend on instance >> state, make it static. It's one way to reduce the scope of a method. [quoted text clipped - 17 lines] > method. I do that to reduce scope of the method, as I understand the > concept of "scope". There are many times when I realize that I have many methods which don't depend on the state of an object of the type they're declared in. I usually also realize that I pass the same set of parameters, or at least related parameters, to the majority of them... From a design point of view, this tells me that the parameters should probably be combined into their own class, and the methods should belong to that class. The new class may be artificial to the problem-space, but greatly simplifies the solution space.
 Signature Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
Lew - 31 Oct 2007 23:28 GMT > There are many times when I realize that I have many methods which don't > depend on the state of an object of the type they're declared in. I [quoted text clipped - 4 lines] > class may be artificial to the problem-space, but greatly simplifies the > solution space. Among the things I like about this advice is that it explains clearly what refactoring is, and how to do it, at a good introductory level that still has meat on it. I will use explication along this line when I have to explain to someone what refactoring is. Thank you.
 Signature Lew
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|