Java final class with constant - java

I must define a class which all it does is hold constants.
public static final String CODE1 = "100";
public static final String CODE2 = "200";
Now I want use these values in other classes. Is it better to use this class as a static class or instantiate it ?
Thanks.
Note : I know enums but in this context, I must use a class.

Just to use the values, you certainly shouldn't instantiate the class. Just because you can access static members as if they were instance members doesn't mean it's a good idea.
If the class really only contains constants - and if you're sure that's a good idea, rather than those constants appearing within classes which are directly related to them - you should make it a final class with a private constructor, so that no-one can pointlessly instantiate it:
public final class Codes {
public static final String CODE1 = "100";
public static final String CODE2 = "200";
// Prevent instantiation
private Codes() {
}
}
Don's answer suggesting using an enum is a very good idea too - it means you can use Code in your API everywhere that you don't need the exact string representation, which prevents you from accidentally using non-code values.

Jons answer is correct, although I want to show you a solution with an enum.
There is a disadvantage in accessing its String value as you have to call Code.CODE1.text() instead of Code.CODE1.
public enum Code {
CODE1("100"), CODE2("200");
private String text;
Codes(String text) {
this.text = text;
}
public String text() {
return text;
}
}

java language spec and JVM spec allow you to do anything you wanted, whether instantiate a class or use final or use other way....
Just use Eclipse and try !
while there is some good practice, Jon Skeet's answer is one good practice.

Java Language is not support global variable
public class ComonFun {
public static final String CODE1 = "100";
public static final String CODE2 = "200";
public static String CODE1(){
return CODE1;
}
public static String CODE2(){
return CODE2;
}
}
implement
public class Main {
public static void main(String[] args) {
System.out.println(ComonFun.CODE1());
System.out.println(ComonFun.CODE2());
}
}

i think that you need simply to declare an interface, you won't need to specify the clause "public static final". and it can be usuable throgh the hall project.

Use them as static, don't go for instantiation.
Even use static import as a benefit.
package coma;
import static coma.ImportStatments.*;
public class UsingClass {
public static void main(String[] args) {
System.out.println(CODE1);
}
}
And the class with final variables would look like this:
package coma;
public class ImportStatments {
public static final String CODE1 = "100";
public static final String CODE2 = "200";
}

Related

Java: make constants accessible anywhere

I have a Java program that should read configuration parameters from file, Like this:
java -jar myapp.jar --config config.txt ...
Once loaded, these parameters do not change and should be accessible by any class in the program.
Is it possible to make these parameters accessible from any class without explicitly adding them as parameter to constructors and methods? For example, I would like to be able to do this:
public class Main {
public static void main(String[] args){
// This list should be visible by any class
List<String> CONFIGS= readMyConfigsFromFile(args[0]);
...
}
}
public class MyClass(){
public MyClass(){
String thisConf= CONFIGS.get(0); // Do something with this conf param taken from Main.
...
}
}
public class MyOtherClass(){
public MyOtherClass(){
String thisConf= CONFIGS.get(0); // Do something with this conf param taken from Main.
...
}
}
...
Is this possible at all? And is it an advisable set up to do? If not, what is the recommended design to go about it?
(I have read similar questions but I'm still unsure if and how it is possible in the situation I described)
You could use the Singleton pattern.
To model it, I assume you have 2 fields in your configuration: a String and an integer.
public class Config {
private static Config INSTANCE;
private final String field1;
private final int field2;
public Config(String field1, int field2) {
this.field1 = field1;
this.field2 = field2;
}
public String getField1() {
return field1;
}
public int getField2() {
return field2;
}
public static Config getInstance() {
if (INSTANCE == null) {
INSTANCE = loadInstance();
}
return INSTANCE;
}
private static Config loadInstance() {
// read your config from properties
String field1 = ...
int field2 = ...
return new Config(field1, field2);
}
}
And then use Config.getInstance() everywhere you need to get that instance.
Please note that this implementation has a flaw: it may be initialized several times if getInstance() gets called from different theads.
Double-checked locking https://en.wikipedia.org/wiki/Double-checked_locking may be used to overcome this flaw if it is important to you to only initialize once.
This solution, like others, would require a mock object to unit test. But I think it's best as it encapsulates the arguments in an immutable object. This also makes thread-safety a non-issue. Use a HashMap instead of an array to access these by key instead of index if you prefer:
public class Main {
public static void main(String[] args){
new CONFIG(readMyConfigsFromFile(args[0]).toArray());
...
}
public static final class CONFIG {
private final String[] args;
private static final CONFIG instance;
private CONFIG(String[] args) {
this.args = args;
instance = this;
}
public static CONFIG getInstance() {
return CONFIG.instance;
}
public String[] getArgs(){
return Arrays.copy(this.args, this.args.length);
}
public String getArg(int index) {
return args[index];
}
}
To get arguments:
Main.CONFIG.getArgs();
"Is this possible at all?". Yes, it is. You can easily do it with the help of static in java
public class Config {
private static final List<String> config = new ArrayList<String>();
public static void addConfig(String value){
config.add(value);
}
public static List<String> getConfig(){
return config;
}
}
To add values to config you can do
public static void main(String[] args) {
//Read value from file here in some variable say configValue
Config.addConfig(configValue);
}
To access config
public class MyOtherClass(){
public MyOtherClass(){
Config.getConfig().get(0); // Do something with this conf param taken from Main.
...
}
}
Note above code is not thread safe. You can make it thread safe by adding synchronization concepts
Now "And is it an advisable set up to do?". It depends on your requirements. As you mentioned these values does not change runtime then you can use this. But is the requirement we need to enforce that these values "should not change" once initialized then answer will be different and you should use something like Singleton Pattern and modify to make sure you can only read and not write once the object is constructed. Also note that with static methods, like I suggested, testing becomes really hard.

How to pass constants to a method?

I have this classes:
package util;
public final class Constant {
private Constant() {
throw new AssertionError();
}
public static class Product {
public static final String CODE = "Product";
public static final String A = "product_5g2g";
public static final String B = "product_a45h";
public static final String C = "product_a3ag";
//more constants..
}
public static class Employee {
public static final String CODE = "Employee";
public static final String A = "employee_1g3f";
public static final String B = "employee_h52d";
public static final String C = "employee_h5d2";
//more constants..
}
public static class Client {
public static final String CODE = "Client";
public static final String A = "client_h5ad";
public static final String B = "client_1df1";
public static final String C = "client_6g23";
//more constants..
}
}
and:
package util;
import util.Constant.*;
public class Main {
public void run() {
if (isSelected(Product.CODE)) {
if (isSelected(Product.A) || isSelected(Product.B)) {
//do something
}
compute(Product.C);
//more similar instruction that use constants from Product class
}
if (isSelected(Employee.CODE)) {
if (isSelected(Employee.A) || isSelected(Employee.B)) {
//do something
}
compute(Employee.C);
//more similar instruction that use constants from Employee class
}
if (isSelected(Client.CODE)) {
if (isSelected(Client.A) || isSelected(Client.B)) {
//do something
}
compute(Client.C);
//more similar instruction that use constants from Client class
}
}
public boolean isSelected(String s) {
return true;
}
public void compute(String s) {
}
}
As you can see, this block of code
if (isSelected(StaticClass.CODE)) {
if (isSelected(StaticClass.A) || isSelected(StaticClass.B)) {
//do something
}
compute(StaticClass.C);
//more similar instruction that use constants from Product class
}
is repetitive, but can't put it in a separate method because java don't permit a static class as a parameter public void method(StaticClass) {}.
How can I refactor the above code? My first thought was to make Singletons that extend a base class, or implement an common interface. There is a better solution?
You should look into using polymorphism here. Example: instead of doing
if (X) {
doY();
}
"good" OO looks much more like:
Y y = getMeSomeY();
y.doTheY();
Where getMeSomeY() returns you exactly that what is required (so Y could be an interface; and that method provides different implementations of that interface which all do slightly different things).
The point is: you wrote procedural code, where you ask something, to then make a decision about it. Good OO favors the opposite (called tell don't ask).
You start by ... not making everything flat strings. By doing so, you give up on the whole "static typing" thing. If your code is making decisions only on strings, why are you programming in Java? You can very well use a non-typed language than. So, at least learn about Java enums; and use those. But please understand: enums are not the real answer here. They would just help to make your code a bit better.
The real problem here is that you want to write code doing these if (x) then y all over the place.
You might have guessed by now: there is no easy answer here. What I would do: first, step back. And have a in-depth look into your design. The code you have right now indicates to me that your underlying object model is far from "helpful". And that is the whole point of OO: you create classes and objects that help you to write clean, elegant code. But when your base design isn't supporting that; then there is no point in trying to refactor the code that came out of that. Because the ugliness of your code is just a symptom; the root cause lies in your design underneath.
What you are looking for is an Enum. Redefine all your classes as Enums instead. For example, you can redfine the Product class as follows :
public enum Product {
CODE("Product"),
A("product_5g2g");
private String value;
//define others constants in a similar fasion
public Product(String value) {
this.value = value;
}
}
Enums can be passed as method parameters. In your particular example, you can do this :
public void method(Constants.Product product) {
}
That said, you should definitely look into an alternative way to achieve your objective. Take a look at Replacing conditionals with Polymorphism for starters.

If enums are implicitly static, why are they able to make use of the "this" keyword internally?

Please forgive the beginner-level question, but I'm confused by the implicit static status of enums.
On one hand, you can't declare them within methods because they are implicitly static, and you can reference them from a static context like any other static class.. but on the other, internally, they refer to themselves as "this" as though they were an instance.
Code sample:
public class EnumTest {
enum Seasons{
SUMMER,
FALL,
WINTER,
SPRING;
public String toString()
{
switch(this)
{
case SUMMER:
return "Hot Summer";
case FALL:
return "Colorful Fall";
case WINTER:
return "Crisp Winter";
case SPRING:
return "Allergy Season";
default
return "wth?";
}
}
}
public static void main(String[] args)
{
System.out.println(EnumTest.Seasons.SUMMER.toString());
}
}
Note how within toString() in the enum definition, there is a switch on "this".
Within the static method main, the Enum is accessed in typical static class manner.
I know that enums are a special type of class, but I'm still trying to understand the reasons for some of their unconventional quirks.
Is there some sort of Factory-pattern type of auto-construction going on when an enum constant is referenced? At exactly what point does it transition from being a static class to an instance?
Thanks!
The constants defined in the enum class are the only things that are implicitly static. It's close to (but not quite equivalent to):
public static final Seasons SUMMER = new Seasons();
public static final Seasons FALL = new Seasons();
public static final Seasons WINTER = new Seasons();
public static final Seasons SPRING = new Seasons();
This allows you to write code such as Seasons.SUMMER.
The rest of the class body is like a normal class body - public String toString() is not implicitly static, therefore it has access to this.
Think of the enum constants as statically declared objects like here:
class A {
public final static A FOO = new A ("FOO");
public final static A BAR = new A ("BAR");
private final String text;
private A(String text) {
this.text = text;
}
public String toString() {
return this.text;
}
}
Although statically declared, the objects for each of the constants can provide non-static methods you can call.

How to create configuration class with static variables in java properly?

I created SomeConfig to store there static data. However I try to understand witch options is better (or none of both)
Before I had class SomeConfig written like:
public class SomeConfig {
private static int mValue = 8;
private static String mString = "some String";
public static int getValue() {
return mValue;
}
public static void setValue(int value) {
mValue = value;
}
public static String getTheString() {
return mString;
}
public static void setValue(String theString) {
mString = theString;
}
}
Now I changed it to:
public class SomeConfig {
private static SomeConfig mSomeConfig = new SomeConfig();
private int mValue = 8;
private String mString = "some String";
public static int getValue() {
return mSomeConfig.mValue;
}
public static void setValue(int value) {
mSomeConfig.mValue = value;
}
public static String getTheString() {
return mSomeConfig.mString;
}
public static void setValue(String theString) {
mSomeConfig.mString = theString;
}
}
Generally i changed private variables to non-static but API stays the same.
What is a difference between two options I posted?
Thanks,
If you want only one instance of your SomeConfig to exist in your application then you might want to make it a Singleton class. Refer to this link : link
Your second option seems to be the closest to being a Singleton, you just need to make your Default constructor Private to ensure that no other class can create another instance of SomeConfig.
As per my understanding static variables are class variable and those are not require any object for calling or assigning value .The values for those static variables are remains same over the class.Once you assign a value, all object can access that value.
Hope it will help you.
Generally, I think it's a good practice to avoid static variables and methods, unless there is a real need (I guess common use of static is "utility" type method, or constants etc). If you do not want to instantiate the class multiple times or want to ensure single instance of the configuration, I think implementing it as a singleton would be a better way to go here.
I wouldn't recommend using any of the two for configuration purposes.
The difference between these two are just that one uses an instance to hold the values, the other uses static variables.
You might look into having a configuration class that utilises a ResourceBundle to load the values from a .properties file during initialisation.

How to initialise a Java enum using an inner static final field?

I am designing a text-only videogame with two characters not often seen together, yet very much alike in heart and disposition.
My problem is that I don't know how to initialise an enum constant through a constructor using a static final inner constant. Otherwise the game is good to go. ;)
Here's the dilemma:
The enum constants must be defined in the first line of the enum, if I am not mistaken
The first line can't refer to anything coming after it (i.e. "cannot reference a field before it is defined")
How do I resolve this catch-22?
Here some sample code released from the game under non-disclosure agreement:
enum ValiantHeroWithPrincessSavingTendencies {
SUPERMARIO(TYPICAL_QUOTE_FROM_MARIO), ZELDA(TYPICAL_QUOTE_FROM_ZELDA);
private String aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive;
public String getQuoteUnderStressfulCircumstances() {
return aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive;
}
private ValiantHeroWithPrincessSavingTendencies(String quote) {
aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive = quote;
}
private static final String TYPICAL_QUOTE_FROM_ZELDA = "Have at ya!";
private static final String TYPICAL_QUOTE_FROM_MARIO = "We, wagliu'!";
}
I am trying to initialise SUPERMARIO using TYPICAL_QUOTE_FROM_MARIO but I haven't defined TYPICAL_QUOTE_FROM_MARIO yet. Moving the private static final field before SUPERMARIO is illegal, I think.
The only viable options are to either a) move your constants to another class or b) just put your constants directly into the value initializers.
If you move your constants, you can make the class a static class in the enum:
enum ValiantHeroWithPrincessSavingTendencies {
SUPERMARIO(Quotes.TYPICAL_QUOTE_FROM_MARIO),
ZELDA(Quotes.TYPICAL_QUOTE_FROM_ZELDA);
private String aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive;
public String getQuoteUnderStressfulCircumstances() {
return aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive;
}
private ValiantHeroWithPrincessSavingTendencies(String quote) {
aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive = quote;
}
private static class Quotes {
private static final String TYPICAL_QUOTE_FROM_ZELDA = "Have at ya!";
private static final String TYPICAL_QUOTE_FROM_MARIO = "We, wagliu'!";
}
}
You can just access them via class name:
enum ValiantHeroWithPrincessSavingTendencies {
SUPERMARIO(ValiantHeroWithPrincessSavingTendencies.TYPICAL_QUOTE_FROM_MARIO),
ZELDA(ValiantHeroWithPrincessSavingTendencies.TYPICAL_QUOTE_FROM_ZELDA);
...
private static final String TYPICAL_QUOTE_FROM_ZELDA = "Have at ya!";
private static final String TYPICAL_QUOTE_FROM_MARIO = "We, wagliu'!";
}
It's simplier than Brian's solution
The private static final constants are local to the enum; just code them in the instance definitions. After that point they can be accessed internally from the aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive variable.
You could always do something hacky like this:
public enum Derp
{
SOMETHING(),
SOMETHINGELSE();
private String herp;
public static final String A = "derp", B = "derp2";
public String getHerp()
{
return herp;
}
static
{
SOMETHING.herp = A;
SOMETHINGELSE.herp = B;
}
}

Categories