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";
...
}
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
As you have mentioned a class with the private Constructors and has all the string constants, is one way, even there is an overhead, that can be negligible
Else you can create a Class with Final Modifier and Define your string constants
You can use the Abstract Class with the String Constants
You can define the string constants in the properties files and can access from that, this will definitely reduce the memory and increase the flexibility of your code.
For me the best explanation is in Effective Java book: Item 4: Enforce noninstantiability with a private constructor (See more)
In Summary:
Private constructor is due utility classes were not designed to be instantiated, so is a design decision. (NO performance or memory overhead)
Making a class abstract doesn't work because can be subclassed and then instantiated.
With an abstract class the user may think the class is for inheritance.
The only way to ensure no instantiation is to add a private constructor which ensures the default constructor is not generated.
Private constructor prevents inheritance because the super constructor cannot be called (so it is not need the declare the class as final)
Throw an error in the private constructor avoids call it within the class.
Definetively, the best way would be something like next:
public class MyStrings {
private MyStrings () {
throw new AssertionError();
}
...
}
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
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.
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.
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.
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.
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.
That's the right way to store some constants, as also suggested in Effective Java (2nd Ed.), item 19.
Related
I am new to Java and am wondering how to create in an elegant way a global object whose members are constant. One way to do this is:
public class Global {
public final static String NAME = "John Doe";
public final static int AGE = 100;
}
and then calling it outside as
import Global;
public static void main(String[] args) {
int age = Global.AGE; // works fine; age cannot be modified
}
The only issue is: I have a lot of variables in this class that I'm copying from a text file and adding the keywords "static", "public", and "final" is cumbersome and makes it look ugly. I know it's not a big issue, but I would like a more elegant solution to this. Any ideas? I have tried nested classes but could not figure out to have it behave correctly.
If you are sure that you will handle only constants you can declare your class as final class and define a private constructor - Doing that, you avoid instantiation (the assertion error will make the class safe even if they try to instantiate the class using reflection), this is an elegant way to consolidate your constants in a class.
public final class Global {
public static final String NAME = "John Doe";
public static final int AGE = 100;
}
private Global() {
//this prevents even the native class from
//calling this constructor as well :
throw new AssertionError();
}
Advantages:
Since the required static memebers are imported statically, the class namespace is not polluted.
The compiled code has one fewer binary compatibility constraint (that “class implements Constants Interface”).
Because static imports apply only to the current file (and not the whole class hierarchy), it is easier to discover where each static member is declared.
Run-time and compile-time semantics are more closely aligned when using static imports instead of constants interfaces.
If required, static blocks can be declared.
Since some answers are suggesting using the interface, I suggest you check out this article Why the Constant Interface Pattern Should Be Discouraged. If you can check out the Effective Java book will be a good reference as well.
You can use interface also
public interface Global {
String NAME = "John Doe";
int AGE = 100;
}
I have an abstract class that has some constants that each child class will use. Each one of them is static, final and immutable.
public abstract class MyAbstract {
//some private instance fields
protected static final long LONG_ID = 1;
protected static final String STRING_ID = "example_id";
//some methods
}
I know that having protected static final is bad practice but what about protected static finals that are immutable?
I know that I can make them public but I'd like to avoid doing so as the constants refer to specific ID's that user doesn't need to know.
To answer your question in the title "What is the best practice of inheriting constants in Java?", my answer is: do not inherit them at all.
Inheritance has a special meaning and purpose in object oriented programming, and using inheritance just for convenience because you want to be able to access constants in a particular set of classes does not correspond to this meaning and purpose.
If you have constants that you want to be able to use in different classes, you can put the constants in a separate class. Make this class final and make the constructor private so that it can't be subclassed and instantiated:
package com.example;
public final class Constants {
public static final long LONG_ID = 1L;
public static final String STRING_ID = "example_id";
// Private constructor, this class should not be instantiated
private Constants() {
}
}
Then, in a class where you want to use the constants, use import static:
import static com.example.Constants.LONG_ID;
public class Example {
public void someMethod() {
// Use the constant
long id = LONG_ID;
System.out.println(id);
}
}
The advantage is that the class Example does not need to extend class Constants or implement an interface, so you do not need to misuse inheritance, while you still have the same convenience of being able to use the constants with concise syntax.
I am using a class to store some strings which I can access across the application. It looks like:
public final class Settings {
public final static class Setting1 {
public final static String CONFIG = "A config string";
private Setting1 (){};
}
public final class Setting2 {
public final static String CONFIG = "A config string";
private Setting2 (){};
}
}
I have found I can use either static nested class (e.g. Setting1) or inner class (e.g. Setting2). They both can be used in the same way:
System.out.println(Settings.Setting1.CONFIG); // Print: A config string
System.out.println(Settings.Setting2.CONFIG); // Print: A config string
So if the nested class will only contain final static fields, are there any different in using these two? Because of the private constructor, no instantiation is allowed. Does that mean these two classes are the same now?
A nested/inner class should be marked static if it does not access the this of the outer class, no non-static fields or methods of the outer class.
In fact it is the other way around: a non-static inner class has an overhead of an outer this: a Settings.this besides the normal this.
So yes, in your case certainly. The reason / role of that inner class is of course style / namespace.
If you wish to store only static final fields, then enum will be better choice than inner class. In fact, you are storing constants using static final fields and enum are provided for this purpose only.
There's no difference in storing such constants. But it's usually not a good code-style.
Yes.
Ordinary constants should always be static and final (and immutable, which is not the same thing as final). If you are going to do it the way you have the inner classes should be static too. You should probably include a private constructor too - to prevent instances of these classes (the inner or the outer) being created.
That said, what would be wrong with?
public final class Settings {
private Settings() { ; }
public static final String SETTING_1 = "A config string";
public static final String SETTING_2 = "Another config string";
}
Re the answer from Florescent Ticket:
Enums are not for storing static final fields (though their members are static final fields). They are for defining a typed, bounded set (with or without further attributes on the members of the set). A typical example is public enum Suit { HEART, CLUB, SPADE, DIAMOND };.
You could represent your Settings this way (with a single String attribute on each member of the enum) but there is no real reason why you should. It might be helpful if you routinely need to deal with sets of settings (and I mean sets of settings - not sets of the values of those settings). On the other hand, it might be less than helpful if you want settings that are not just strings.
The simplest starting point is probably too just define a class with public static final constants (they should be immutable too, of course) of the appropriate values - whether strings or whatever. But if you want inner classes (perhaps to group the settings) then the inner classes should be static and final (and ideally, also have a private constructor, to prevent instances).
I'd like to have Java constant strings at one place and use them across whole project (many classes).
What is the recommended way of achieveing this?
public static final String CONSTANT_STRING="CONSTANT_STRING";
constants should be:
public - so that it can be accessed from anywhere
static - no need to create an instance
final - since its constants shouldnt be allowed to change
As per Java naming convention should be capitalized so that easy to read and stands out in Java documentation.
There are instances where interfaces are used just to keep constants, but this is considered a bad practice because interfaces are supposed to define the behavior of a type.
A better approach is to keep it in the class where it makes more sense.
for e.g.
JFrame has EXIT_ON_CLOSE contant, any class which subclasses JFrame will have access to it and it also makes sense to keep in JFrame and not in JComponent as not all components will have an option to be closed.
As #mprabhat answered before, constants should be public, static, final, and typed in capital letters.
Grouping them in a class helps you:
Don't need to know all the constants you have. Many IDEs (like Eclipse) show you the list of all the fields a class has. So you only press CTRL+SPACE and get a clue of which constants you can use.
Making them typesafe at compile time. If you used Strings, you might misspell "DATABASE_EXCEPTION" with "DATABSE_EXSCEPTION", and only notice during execution (if you are lucky and notice it at all). You can also take profit of autocompletion.
Helping you save memory during execution. You'll only need memory for 1 instance of the constant.
I.E: (a real example) If you have the String "DATABASE_EXCEPTION" 1000 times in different classes in you code, each one of them will be a different instace in memory.
Some other considerations you might have:
Add javadoc comments, so programmers who use the constants can have more semantic information on the constant. It is showed as a tooltip when you press CTRL+SPACE. I.E:
/** Indicates an exception during data retrieving, not during connection. */
public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
/** Indicates an exception during the connection to a database. */
public static final String DATABASE_CONNECTION_EXCEPTION =" DATABASE_CONNECTION_EXCEPTION";
Add semantic to the identifier of the constant. If you have the constant "Y", and sometimes means yes and other times year, consider using 2 different constants.
public static final String Y = "Y"; // Bad
public static final String YEAR = "Y";
public static final String YES = "Y";
It will help you if, in the future, decide to change the values of the constants.
/** Year symbol, used for date formatters. */
public static final String YEAR = "A"; // Year is Año, in Spanish.
public static final String YES = "S"; // Yes is Sí, in Spanish.
You might not know the value of your constants until runtime. IE: You can read them from configuration files.
public class Constants
{
/** Message to be shown to the user if there's any SQL query problem. */
public static final String DATABASE_EXCEPTION_MESSAGE; // Made with the 2 following ones.
public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
public static final String MESSAGE = "MESSAGE";
static {
DATABASE_EXCEPTION_MESSAGE = DATABASE_EXCEPTION + MESSAGE; // It will be executed only once, during the class's [first] instantiation.
}
}
If your constants class is too large, or you presume it'll grow too much in the future, you can divide it in different classes for different meanings (again, semantic): ConstantDB, ConstantNetwork, etc.
Drawbacks:
All the members of your team have to use the same class(es), and the same nomenclature for the constants. In a large project it wouldn't be strange to find 2 definitions:
public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
public static final String EXCEPTION_DATABASE = "DATABASE_EXCEPTION";
separated several hundreds of lines or in different constant classes. Or even worse:
/** Indicates an exception during data retrieving, not during connection. */
public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
/** Indicates an exception during data retrieving, not during connection. */
public static final String EXCEPTION_DATABASE = "EXCEPTION_DATABASE";
different identifiers, for different values, having the same meaning (and used for the same purposes).
It might make readability worse. Having to write more for doing the same:
if ("Y".equals(getOptionSelected()) {
vs
if (ConstantsWebForm.YES.equals(getOptionSeleted()) {
How should constants be ordered in the class? Alphabetically? All related constants together? In order as they are created/needed? Who sould be responsible of the order being correct? Any (big enough) reordering of constants would be seen as a mess in a versioning system.
Well, it's taken longer than what I expected. Any help/critics is/are welcome.
You should create a class of the constants that stores all the constants.
like ProjectNameConstants.java
which contains all the constant string static as you can access it through the classname.
e.g.
classname : MyAppConstants.java
public static final String MY_CONST="my const string val";
you can access it as
MyAppConstants.MY_CONST
Best practice is to use Java Enum (After Java 5)
Problems with the class approach:
Not typesafe
No namespace
Brittleness
Please check java docs.
public enum Constants {
CONSTANT_STRING1("CONSTANT_VALUE1"),
CONSTANT_STRING2("CONSTANT_VALUE2"),
CONSTANT_STRING3("CONSTANT_VALUE3");
private String constants;
private Constants(String cons) {
this.constants = cons;
}
}
Enums can be used as constants.
Edit: You can call this Constants.CONSTANT_STRING1
Create a class called Constants at the base of your main package (i.e. com.yourcompany) with all your constants there. Also make the the constructor private so no object will be created from this class:
public class Constants {
private Constants() {
// No need to create Constants objects
}
public static final String CONSTANT_ONE = "VALUE_CONSTANT_ONE";
public static final String CONSTANT_TWO = "VALUE_CONSTANT_TWO";
}
public class SomeClass {
public static final String MY_CONST = "Some Value";
}
If it is supposed to be a pure constants class then make the constructor private as well.
public class Constants {
public static final String CONST_1 = "Value 1";
public static final int CONST_2 = 754;
private Constants() {
}
}
Then it won't be possible to instantiate this class.
You should break up your constants into groups they belong, like where they'll be used most, and define them as public static final in those classes. As you go along, it may seem appropriate to have interfaces that define your constants, but resist the urge to create one monolithic interface that holds all constants. It's just not good design.
I guess the correct answer you're looking for is
import static com.package.YourConstantsClass.*;
Create a public class and for each constant string create a field like this
public static final String variableName = "string value";
public enum Constants {
CONSTANT_STRING1("CONSTANT_VALUE1"),
CONSTANT_STRING2("CONSTANT_VALUE2"),
CONSTANT_STRING3("CONSTANT_VALUE3");
private String constants;
private Constants(String cons) {
this.constants = cons;
}
#JsonValue
#Override
public String toString() {
return constants;
}
}
Use it Constants.CONSTANT_STRING1.toString()
I'm learning Java and I just wonder why public and private is used when a method or members is static? When static is used they are class methods and class members and could be used from other classes without creating an object, so is public and private necessary? Some help is preciated to understand. Sorry if this question is too simple for some.
The accessibility of a field or method is orthogonal to the fact that it's static or not.
You could have a static method accessible from the outside, and a static method that must only be used from inside the class itself (by other static or non-static methods). The same goes for fields.
For example:
// not visible from the outside
private static final long MILLISECONDS_IN_A_MINUTE = 1000L * 60 * 60;
public static Date addMinutes(Date d, int amount) {
return addMillis(d, MILLISECONDS_IN_A_MINUTE * amount);
}
// not visible from the outside
private static Date addMillis(Date d, long amount) {
return new Date(d.getTime() + amount);
}
It's not necessary, but there can be static methods and data members for internal use only.
An example for this is if you want an unique id for every instance of the class:
class Foo
{
private static int nextId = 0;
private static int generateId() { return ++nextId; }
private int id;
public Foo()
{
id = generateId();
}
}
As you can see, nextId and generateId() are not needed outside the class, nor should they be used outside the class. The class itself is responsible for generating id's. But you need them to be static (well, you need nextId to be static, but you can also make generateId() static since it doesn't access non-static members).
Whenever an object Foo is created, the static counter is incremented, thus you get different ids for each instance of the class. (this example is not thread-safe)
Suppose you have a static public method and this method must access to a private attribute. This private attribute must be static too. There's one reason why private static exists.
Example :
public class Test {
private static int myattr = 0;
public static void foo() {
myattr = 2;
}
}
Above, myattr must be a static attribute in order to use it in the foo() method.
Yes it is needed.
If you have a Static Method and want to use a private variables in that method, then you need to declare it static too.
Or you want the static variables not be visible to other packages, then don't declare it public.
From what I remember, it's not really needed. But public means, basically in any programming language, that it can be used by outside files. With private it can only be used within that file, and static means you cannot change the value of said reference. Whether these be functions, or variables, the same rules apply. I might be off. Haven't done Java in about a year and a half.
The ways you can incorporate these types is up to you. After all, a program is only as diverse as it's user. ^_^
Public and private keywoards have to do with visibility: which members do you want to accessible to other classes and which should be hidden or encapsulated.
Static members relate to the class as a whole, while non-static members operate on object instances.
I'm learning Java and I just wonder why public and private is used when a method or members is static?
I believe your question is due to a common misconception that the access modifiers are for instances, but they're not!
Two different instances can access each others private members if they are of the same class.
In other words, the access modifiers works on class level. Since also static members belong to some class, it makes sense to have access modifiers also on them.
A static method (or variable) that should only be used by code in the same class (as in the example by JB Nizet) should be private, while a static method or variable that may be used by code in any class should be public.
When the static is used with methods it doesn't only mean that it should be used by the members of other classes.
The case when we access the static methods of a class is one when
the class (which contains the method) cannot be instantiated i.e. no objects can be created of that class.
There may be situations when two different classes may have static methods with same name. In that case you want to use the method of the same class not the method of other class.