Prev: Initializing a Map in an Interface?
Next: Urgent Opening for Senior .Net Engineer position with our direct client in Milpitas, CA
From: Arne Vajhøj on 15 Mar 2010 20:22 On 15-03-2010 16:50, Rhino wrote: > I have a class named StringUtils containing several utility methods. The > class is stored in a package called "common" because it could potentially > be utilitized by lots of other classes. The methods in this class include > count(), which determines the number of occurrences of a character in a > string, and blanks(), which creates a String containing the number of > blanks specified in the input parameters (for example, blanks(4) > generates a String containing 4 blanks). > > I'm trying to figure out if this utility class should be defined final > and have all of its methods defined as static, just the way things work > with the Math class, so that my classes could be referenced statically. > For example, if the methods were static, I would write my code like this: > > int num = StringUtils.count("a", "foo"); > System.out.println(StringUtils.blanks(4) + "Hello world"); > > Or would it be better to have a StringUtils NOT be final and NOT make its > methods static? In that case, I'd have to instantiate StringUtils, then > use the reference to the instance to use the methods, like this: > > StringUtils myUtils = new StringUtils(); > int num = myUtils.count("a", "foo"); > System.out.println(myUtils.blanks(4) + "Hello world"); > > Either way will work but which is the better design and why? Make the methods that are static in nature static. And that may be all of them. And no need to mess around with final or private constructor. It is pointless but harmless if somebody would inherit or initialize the class. Make the methods static and move on to a real problem. Arne
From: Rhino on 16 Mar 2010 13:42 > A class who will never have instances with their own state, whose sole > purpose is to provide utility methods for other classes, whose entire > operation depends only on data in the argument lists of those methods, > and ultimately, for whom it really never adds value to have an > instance, is called a "utility class" and likely should have > instantiation prevented and all its members static. > > Declaring a class final does not prevent its instantiation. Declaring > its constructor private does, and also prevents subclassing, making > the 'final' declaration redundant, so don't bother with it. > I've read all the replies to this thread and have been trying to post followup questions since yesterday afternoon; unfortunately, I've had major problems with the news server and have finally had to resort to posting via Google groups. Sorry for the delay! -- Am I correct in assuming that a valid example of 'state' is the Locale used by the class/methods to generate error messages? My StringUtils class generates a substantial number of error messages via the standard ResourceBundle mechanism and delivers them in a Locale-sensitive fashion. I have two constructors for StringUtils, one that has no parameters and simply uses the default Locale, and the other, which has the Locale desired by the user as the single parameter. Now, if I want to continue to deliver Locale-sensitive messages and if I make the constructors private, I can't tell the methods which Locale to use in selecting message files via the constructor. I suppose I could add a Locale parameter to each method's parameter list but that seems ugly. What's the best way to handle Locale-sensitive messages if I want to keep my methods static and my constructors private? Or does this factor change everything and now justify keeping the StringUtils constructors public and its methods non-static? -- Rhino
From: Rhino on 16 Mar 2010 13:50 On Mar 15, 5:00 pm, markspace <nos...(a)nowhere.com> wrote: > Rhino wrote: > > I have a class named StringUtils containing several utility methods. > > I asked aquestionlike this here long ago. What I think now is that > you almost certainly should make the class final, and all the methods > static. > > If you do need to keep state, make a new class, don't reuse the > StringUtils, except as a factory. > Sorry, I'm not following this strategy. I'm not entirely sure what constitutes 'state' in this context but I suspect that the Locale-specific messages I am generating may qualify. As I've explained in my reply to Lew's first response, I am generating Locale-sensitive error messages. I have two constructors. One constructor has no parameters and uses the default Locale; the other constructor has the Locale as its parameter and generates messages appropriate for that Locale. If this counts as "state" for the purposes of our current discussion, I'm not clear on what you're proposing. How do I use StringUtils as a factory to feed the new class that you are suggesting? > And as Lew says, the best way to make such a class final is to make the > constructor private. That kills two birds with one stone. First the > class is final because subclasses can't call the constructor, and second > other classes can make instances of your utility class either. > > One last idea, I have a string utility class that is declared something > like this: > > package mypackage.common.stringutils; > > public class StringUtils { ... > > In other words, the package name is stringutils, and so is the class > name. This allows me to easily add classes to the stringutils package, > without trying to overload StringUtils to hold state. For example, if > RepeatedString is a class that tries to be faster than blanks(), but > requires a max length: > > package mypackage.common.stringutils; > > public class RepeatedString { > final private String repeated; > public RepeatedString( String s, int dups ) { > StringBuilder sb = new StringBuilder( s.length() * dups ); > for( int i = 0; i < dups; i++ ) { > sb.append( s ); > } > repeated = sb.toString(); > } > public String subStr( int count ) { > return repeated.substring( 0, count ); > } > > } > > This just allows me to have a nicer place to put RepeatedString (under > stringutils) rather than have to find a place to shoe-horn it in > somewhere else. I'm not quite clear on why this is better than simply creating a RepeatedString method in the StringUtils claas. Can you clarify, please? -- Rhino
From: markspace on 16 Mar 2010 14:02 I'm quoting your entire message below since a lot of folks here filter Google groups. Short answer: If you're creating a class with instance variables, that's "state" and you should not be using static methods. Basically, since you left out this important detail, all the advice you got on this thread is wrong. Yes, a class that needs constructors for arguments/initialization needs public constructors. public class StringUtils { private Locale locale; public StringUtils( Locale l ) { locale = l; } public String count( String dup, int count ) { ... } ... } Note now I'm avoiding the static keyword everywhere. Rhino wrote: >> A class who will never have instances with their own state, whose sole >> purpose is to provide utility methods for other classes, whose entire >> operation depends only on data in the argument lists of those methods, >> and ultimately, for whom it really never adds value to have an >> instance, is called a "utility class" and likely should have >> instantiation prevented and all its members static. >> >> Declaring a class final does not prevent its instantiation. Declaring >> its constructor private does, and also prevents subclassing, making >> the 'final' declaration redundant, so don't bother with it. >> > > I've read all the replies to this thread and have been trying to post > followup questions since yesterday afternoon; unfortunately, I've had > major problems with the news server and have finally had to resort to > posting via Google groups. Sorry for the delay! > > -- > Am I correct in assuming that a valid example of 'state' is the Locale > used by the class/methods to generate error messages? > > My StringUtils class generates a substantial number of error messages > via the standard ResourceBundle mechanism and delivers them in a > Locale-sensitive fashion. I have two constructors for StringUtils, one > that has no parameters and simply uses the default Locale, and the > other, which has the Locale desired by the user as the single > parameter. > > Now, if I want to continue to deliver Locale-sensitive messages and if > I make the constructors private, I can't tell the methods which Locale > to use in selecting message files via the constructor. I suppose I > could add a Locale parameter to each method's parameter list but that > seems ugly. > > What's the best way to handle Locale-sensitive messages if I want to > keep my methods static and my constructors private? > > Or does this factor change everything and now justify keeping the > StringUtils constructors public and its methods non-static? > > -- > Rhino
From: markspace on 16 Mar 2010 14:03
Rhino wrote: > On Mar 15, 5:00 pm, markspace <nos...(a)nowhere.com> wrote: >> Rhino wrote: >>> I have a class named StringUtils containing several utility methods. >> I asked aquestionlike this here long ago. What I think now is that >> you almost certainly should make the class final, and all the methods >> static. >> >> If you do need to keep state, make a new class, don't reuse the >> StringUtils, except as a factory. >> > Sorry, I'm not following this strategy. > > I'm not entirely sure what constitutes 'state' in this context but I It basically means "an instance variable." > suspect that the Locale-specific messages I am generating may qualify. > As I've explained in my reply to Lew's first response, I am generating > Locale-sensitive error messages. I have two constructors. One > constructor has no parameters and uses the default Locale; the other > constructor has the Locale as its parameter and generates messages > appropriate for that Locale. If this counts as "state" for the > purposes of our current discussion, I'm not clear on what you're > proposing. How do I use StringUtils as a factory to feed the new class > that you are suggesting? > > >> And as Lew says, the best way to make such a class final is to make the >> constructor private. That kills two birds with one stone. First the >> class is final because subclasses can't call the constructor, and second >> other classes can make instances of your utility class either. >> >> One last idea, I have a string utility class that is declared something >> like this: >> >> package mypackage.common.stringutils; >> >> public class StringUtils { ... >> >> In other words, the package name is stringutils, and so is the class >> name. This allows me to easily add classes to the stringutils package, >> without trying to overload StringUtils to hold state. For example, if >> RepeatedString is a class that tries to be faster than blanks(), but >> requires a max length: >> >> package mypackage.common.stringutils; >> >> public class RepeatedString { >> final private String repeated; >> public RepeatedString( String s, int dups ) { >> StringBuilder sb = new StringBuilder( s.length() * dups ); >> for( int i = 0; i < dups; i++ ) { >> sb.append( s ); >> } >> repeated = sb.toString(); >> } >> public String subStr( int count ) { >> return repeated.substring( 0, count ); >> } >> >> } >> >> This just allows me to have a nicer place to put RepeatedString (under >> stringutils) rather than have to find a place to shoe-horn it in >> somewhere else. > > I'm not quite clear on why this is better than simply creating a > RepeatedString method in the StringUtils claas. Can you clarify, > please? RepeatedString has state (the "repeated" field), we all assumed your static class did not. Mixing the two would be a bad idea. |