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.
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;
}
So a while back I created a SQLiteHelper Class in my Android App. I'm not 100% certain why, but the table and column names were public static final fields in a nested public static abstract class. As I recall, the goal was to protect the fields from being modified. It all works great but things are starting to get sophisticated with my app and I want to populate fields in other classes with the public static final table and column name fields. After some trial and error, and reading about abstract classes, static classes, and nesting classes, it occurred to me that can just call the field directly, as in.
String myTable = MySQLiteHelper.dbFields.TABLE_NAME_REMINDER;
Even though I've read up on these topics, how it all comes together in my specific case is still making me scratch my head. So my question is, since the fields are static final, does nesting the fields actually provide additional protection, and if the nested class is static, why also make it abstract? Is static AND abstract required to call it directly without needing to instantiate the outer and nested classes?
Thanks for the help. I'm really trying to get my head wrapped around the various class implementations.
Here's the key elements of the class :
public class MySQLiteHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "Reminders.db";
private static final int DATABASE_VERSION = 5;
public int DatabaseVersion = DATABASE_VERSION;
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public static abstract class dbFields implements BaseColumns {
//dbFields Table Fields
public static final String TABLE_NAME_REMINDER = "reminders";
public static final String COLUMN_REMINDER_ID = _ID;
public static final String COLUMN_REMINDER = "reminder";
public static final String COLUMN_REMINDER_ALTITUDE = "altitude";
public static final String COLUMN_REMINDER_USED = "is_used";
public static final String COLUMN_REMINDER_LASTUSED = "last_used";
public static final String COLUMN_REMINDER_ACTION = "action";
public static final String COLUMN_REMINDER_SCORE = "score";
public static final String COLUMN_REMINDER_RELATIONSHIP = "relationship";
//Special_Days Table Fields
public static final String TABLE_NAME_SPECIAL_DAYS = "special_days";
public static final String COLUMN_SPECIAL_DAYS_ID = _ID;
public static final String COLUMN_SPECIAL_DAYS_DATE = "date"; //dbDataRow strField 1
public static final String COLUMN_SPECIAL_DAYS_NAME = "name"; //dbDataRow dbData
public static final String COLUMN_SPECIAL_DAYS_ALTITUDE = "altitude"; //dbDataRow intField 1
public static final String COLUMN_SPECIAL_DAYS_USED = "is_used"; //dbDataRow Field 2
public static final String COLUMN_SPECIAL_DAYS_WARNING = "warning"; //dbDataRow intField 3
public static final String COLUMN_SPECIAL_DAYS_ACTION = "action"; //dbDataRow intField 4
}
}
since the fields are static final, does nesting the fields actually provide additional protection
No, it doesn't. As you've seen, you can access the fields even if they're nested and, since they're static and final, you can't modify them.
and if the nested class is static, why also make it abstract? Is static AND abstract required to call it directly without needing to instantiate the outer and nested classes?
The purpose of abstract is to allow you to have a base class that has a method with no implementation. One classic example is an Animal class. All animals make a noise (probably not, but let's pretend) so the Animal class should have a makeNoise method. But, every animals noise is different so it doesn't make sense to have any implementation in the base class. The Cat subclass might look like public String makeNoise() { return "meow"; } and the Dog subclass might return "woof", but there's no sane implementation of makeNoise on the base class. However, if you didn't have any makeNoise on the base class you couldn't ask an arbitrary animal to makeNoise. So you'd have a public abstract String makeNoise() method on the base. That lets you call makeNoise for any animal even if all you have is a reference to an Animal.
Note that abstract has nothing to do with the class being nested or not. Other classes, nested or not, can inherit from a nested static class. It also has nothing to do with hiding data or otherwise protecting data or code.
So, to answer your question: you should make it abstract if and only if the purpose of being abstract applies here. Given your sample code, it doesn't.
since the fields are static final, does nesting the fields actually provide additional protection
Not if the nested class is public: it just provides a notational inconvenience.
and if the nested class is static, why also make it abstract?
No idea, it's your class.
Is static AND abstract required to call it directly without needing to instantiate the outer and nested classes?
No, static is sufficient.
I don't see any need for the BaseColumns interface here either. I would look seriously at using an Enum for the column names.
public interface AFEvent {
public String UNKNOWN ="Unknown";
public String ERROR = "EQUINOX_EVENT_ERROR";
public String REJECT = "EQUINOX_EVENT_REJECT";
public String ABORT = "EQUINOX_EVENT_ABORT";
}
And
public class AFEvent {
public static final String UNKNOWN ="Unknown";
public static final String ERROR = "EQUINOX_EVENT_ERROR";
public static final String REJECT = "EQUINOX_EVENT_REJECT";
public static final String ABORT = "EQUINOX_EVENT_ABORT";
}
Then I can call it in the same way.
Whats the difference when calling attribute from interface vs static class ?
fields declared in interface are by default static and final. So, no difference if they are to be used as final constants.
On using final properties, there is no difference. The main difference between interfaces and classes is that on interfaces you can not provide a method implementation but only contracts, in order to force any class implementing your interface to provide implementations for those method contracts. On classes, you can provide method implementations (and contracts, if declared abstract).
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).
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.