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()
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 am getting sonar vilation Performance - Huge string constants is duplicated across multiple class files.
What is the reason i am getting this?
How to resolve this?
This is the code
public static final String GET_CO_ADMIN_GRID_DTLS ="A 30 line huge query";
Solution : Performance - Huge string constants is duplicated across multiple class files.
1.Declare the class as final , make the field as public static final and assign inside static block.
2.Dont Forget to declare private constructor otherwise sonar will show "utility classes should not be public or default constructor as (MAJOR issue)".
public final class QueryConstants {
/**
* Default Constructor.
*/
private QueryConstants(){
//
}
public static final String COMMON_SELECT;
static {
COMMON_SELECT = "Your Query Here";
}
It is because of final keyword. the final field coppied into reference class also.
A large String constant is duplicated across multiple class files. This is likely because a final field is initialized to a String constant, and the Java language mandates that all references to a final field from other classes be inlined into that classfile. See JDK bug 6447475 for a description of an occurrence of this bug in the JDK and how resolving it reduced the size of the JDK by 1 megabyte.
We need to remove final keyword from that string....
The answer from Gowtham is the right one. Creating a Constants class doesn't solve the problem
// creating the constants class like this would lead into duplication of the huge string assigned to FOO
// class A and B would also contain the huge string, after compilation
class C {
public static final String FOO = "HUGE STRING";
}
class A {
public void f() {
String c = C.FOO;
}
}
class B {
public void f() {
String c = C.FOO;
}
}
creating the constant class like proposed in the mentioned bug report http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6447475 avoid the duplication of the huge string
class C {
public static final String FOO;
static {
FOO = "BAR";
}
}
If the string constant is same, then create a Constants file and place that constant there. Use that constant in your multiple class files. like:
Constants.CONSTANT_1
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 want to declare some static variables and use them a lot in my code, so in this example if I want to change the phone number I will change it in one place:
public class AppInformation{
static String phone_number="44444444";
}
So now I could get the phone_number by calling the class :
AppInformation.phone_number;
Another solution:
public class AppInformation {
public static String get_phone_number(){
return "44444444";
}
}
Now I could call the method:
AppInformation.get_phone_number();
Actually I prefer the second method because it is thread safe!
Is this correct? Are there any other suggestions?
Declare it as public static final String PHONE_NUMBER = "44444444". Since you can only read this variable, it is thread-safe.
Why I named it PHONE_NUMBER, not phoneNumber (or breaking all known to me Java conventions phone_number), is explained here.
You can declare it as
static final String phone_number="44444444";
And do not worry about threadsafe anymore :)
What you are saying is that you want a constant, which in Java, is commonly expressed like this:
public class AppInformation
{
public static final String PHONE_NUMBER = "44444444";
}
Note, in your example you've missed:
the access modifier, which in the case of a class means the value would be package private.
the final keywork, which means the value could be modified when the program is running.
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.