views:

300

answers:

8

Hi guys!

Right now I'm thinking about adding a private constructor to a class that only holds some String constants.

public class MyStrings {
  // I want to add this:
  private MyString() {}

  public static final String ONE = "something";
  public static final String TWO = "another";
  ...
}

Is there any performance or memory overhead if I add a private constructor to this class to prevent someone to instantiate it?

Do you think it's necessary at all or that private constructors for this purpose are a waste of time and code clutter?

UPDATE

I'm going for a final class with private constructor and a descriptive javadoc for the class. I can't use a ENUM (which I'd prefer) because I'm stuck on Java 1.4 for now. This would be my modification:

/**
 * Only for static access, do not instantiate this class.
 */
public final class MyStrings {
  private MyString() {}

  public static final String ONE = "something";
  public static final String TWO = "another";
  ...
}
A: 

A synthetic public constructor would have been generated any way. So no.

Really a few bytes out of hundreds of millions at runtime isn't going to make much difference.

I also suggest making the class final and just for completeness have the constructor throw an exception.

If you want terse source code, you could create an enum with no values. Might cause some confusion with beginner programmers though.

Tom Hawtin - tackline
Java only synthesizes a default public constructor if there are *no* others. A private constructor prevents the generation of the default.
Donal Fellows
+2  A: 

I would rather use an enum to hold that Strings. This would ensure that wherever you use that Strings, you only get passed in one of the allowed Strings.

bert
A: 

That's the right way to store some constants, as also suggested in Effective Java (2nd Ed.), item 19.

PartlyCloudy
+1  A: 

If your class has only static members, then there is no need to have a private or public constructor. All members are accessible even without an object. In fact I find it confusing to have a constructor in such a case.

kgiannakakis
If you don't have a constructor at all, the compiler will provide you with one - which will be public, allowing people to construct an instance. The point of a private constructor is to prevent this.
Jon Skeet
@Jon which in the provided scenario has no point given all members are static and final. There's not much one can do with an instance of this class, so preventing it from being instantiated is pointless IMO. Well, it prevents someone from using an extended class, but a `final` class solves that.
jweyrich
@jweyrich: The point of preventing it from being instantiated is that you shouldn't *allow* users to do something which is pointless. (This is why static classes exist in C#.) If there is no purpose in ever creating an instance of the class, your code should prevent it from occurring. A simple private constructor with a comment of "// prevent instantiation" is fine IMO.
Jon Skeet
The private constructor (without the "Prevent instantiation" comment) is confusing for readers of the code. One may think that some kind of initialization needs to take place.
kgiannakakis
@Jon sure, I understand your point, but personally I don't care if someone will instantiate or extend it. Since there's no real implication, I see this as personal style/taste.
jweyrich
@jweyrich: Suppose someone *does* instantiate it. They're misusing your class. Don't you want to discourage that? @kgiannakakis: That's why I'd include the comment :) (There'd also be an appropriate comment in the javadoc.)
Jon Skeet
@Jon for being an _inoffensive_ action, I wouldn't take any extra precaution. I'm probably not aware of all the meanings of "misusing" (english isn't my mother tongue), but sounds subjective to me. IMO, preventing this instantiation is excessive precaution, since nothing bad could happen from it.
jweyrich
@jweyrich: It's inoffensive, but it means that the caller doesn't understand the point of your class and how it's meant to be use. For a mere few lines of code, you can make your design more obvious - i.e. I really don't intend anyone to ever instantiate this class, because there's no reason to do so - which helps steer people into the *correct* way to use the class.
Jon Skeet
@Jon oh, please, keep this guy away from knives -) Point taken.
jweyrich
+2  A: 

If you don't won't anyone to make an object of the class you could make it abstract like this

public abstract class MyStrings {
  public static final String ONE = "something";
  public static final String TWO = "another";
}

and access your static variables like this

String val1 = MyStrings.ONE;
String val2 = MyStrings.TWO;

I think this would be a nicer solution.

jweber
But you can still extend the class, which could be prevented in a final class. Adding the private constructor will then also prevent instances and then you're done.
PartlyCloudy
Yes you're right about that it can be extended, you got a point there. I haven't though about that, nice solution with the final class and the private constructor.
jweber
I would go with this approach. If someone took the trouble to extend the abstract class and then instantiate it, then he must have a very good reason to do so.
Rosdi
@Rosdi: your optimism is refreshing!
Joachim Sauer
+3  A: 

You could add a private constructor, but there are two other options.

In the same situation I would use an enumerator. If it makes sense to your implementation, you could use that instead, if it's public or private depends on where you need to use it:

public enum MyStrings {

  ONE ("something"),

  TWO ("something else");

  private String value;

  private MyStrings(String str) {
     this.value = str;
  }

}

Another option would be to put it in an abstract class, those can not be instantiated:

public abstract MyStrings {

  public static final String STUFF = "stuff";
  public static final String OTHER = "other stuff";
}

Access for both enumerator and abstract class works just like with the implementation you presented:

MyStrings.STUFF
Lars Andren
I also think using an enum is the way to go here. I would also override the toString method.
Ubersoldat
Ah, I forgot to mention that this class is used with Java 1.4. I'd like to have it in 1.5+, but you know, you don't always get what you want... ;-)I'd go for the ENUM and a final class with a newer version of Java too.
cringe
A: 

There is no performance or memory overhead if you add a private constructor in this case. As well, it is not needed since your public static variables are shared among all instances of your object.

Chris J
+1  A: 

Use of private constructor to prevent instantiation of class?

There are several ways you can think of users preventing from the Instantiations for the purpose of creating the Constants

  1. As you have mentioned a class with the private Constructors and has all the string contants, is one way, even there ia a overhead, that can be negligible
  2. Else you can create a Class with Final Modidifier and Define your string constants
  3. You can use the Abstract Class with the String Constants
  4. You can define the string constants in the properties files and can access from that, this will defnitely reduce the memory and increase the flexibility of your code.
harigm