where to put constant used in a java class? - java

I would like to know where to put constants which is only used in one java class? My code creates a name for a shared memory says "sharedMemory" , but I am not sure if I should put in separate Java file or just define in the same class as private static final String SHARED_MEMORY = "sharedMemory". I need this variable only in specific class. Also,if i define in same class should i make it static?
class ABC{
private static final String SHARED_MEMORY = "sharedMemory"; // OK to define in same class or in separate constants file
public void get(){
String name;
if(checIfSharedMemoryNeeded()){
name = SHARED_MEMORY;
}
}
private boolen checIfSharedMemoryNeeded(){
return (x.equals("yuiyr") && y.equals("yweir"))
}
}

Define constants that you only need in a single class in that class and make them private. You can make sure it will not accidentally be used anywhere else.
private static final String ONLY_FOR_THIS_CLASS = "only here";
Define constants that are contextually bound to a specific class but may be needed in other classes in that class they are contextually bound to, but make them public.
public static final String CONTEXTUALLY_FOR_THIS_CLASS_BUT_USABLE_ANYWHERE = "everywhere";
It will allow the usage in other classes like
String constantValueFromOtherClass = OtherClass.CONTEXTUALLY_FOR_THIS_CLASS_BUT_USABLE_ANYWHERE;
Think about writing an enum if the idea of a class that only holds public constants comes to your mind. In many cases, enums will be the better solution.

There are no common guidelines for what to do. Since it only used at one place, I recommend you to leave it in the class where it is used.
Unless you want to change the value in the future and you have many other hardcoded values that you want to change later, then I recommend that you make a class Config that holds all these values.

If this constant is only used for this class, then you should declare are the same class scope.
Now you gotta think if you are going to change the value in the future. If you do, and your application scales, it is better to create a .properties file to hold all the values and load to your app.

The general convention for non-global constants in Java is to write it with private static final like so:
class Foo {
private static final String bar = "foobar";
...
}

If you want to use this variable (SHARED_MEMORY) in ABC class then private access specifier is okay, and if this variable is part of your class not object then using static is a good idea.

Related

Is there any need to use "static" keyword for final variables in Java? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I am confused with final and static keywords in Java and I need to be clarified about the following issues:
1. For variables, is there any need to use static? For example:
public final int ERROR_CODE = 200;
I think there is no need to use static as shown below. Am I wrong?
public static final int ERROR_CODE = 200;
2. As far as I know, static is meaningful for methods, classes to use them without creating their instances. BUT, also using a static variable in this static methods is also meaningful to change their values at the same time:
public class MyClass {
public static int myVariable = 0;
}
//Now in some other code creating two instances of MyClass
//and altering the variable will affect all instances
MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();
MyClass.myVariable = 5; //This change is reflected in both instances
3. Can I change the order of final and static keywords e.g.
public static final int ERROR_CODE = 200;
or
public final static int ERROR_CODE = 200;
static and final are different concepts. A static member belongs to a class instead of an instance whereas you can not re-assign a final variable.
MyClass.myVariable = 5; //This change is reflected in both instances
➡️ It would not have been possible had myVariable been declared final.
Can I change the order of final and static keywords e.g.
public static final int ERROR_CODE = 200; or
public final static int ERROR_CODE = 200;
➡️ Yes. It doesn't make any difference.
1: static is not needed as long as the constant is only accessed from within an instance (or using an instance). But to access it without having an instance, it must be static. More important IMHO, it should be a class variable since there makes no sense to have an instance variable that is constant (independent of the instance) - see also next point.
2: that what you described is the functionality - kind of related, the data design, the data model, static indicates a class member (field, method) in contrast to an instance member - important part of OO design
3: the order is not important... but, the Java Language Specification suggests:
MethodModifier:
(one of)
Annotation public protected private
abstract static final synchronized native strictfp
...
If two or more (distinct) method modifiers appear in a method declaration, it is customary, though not required, that they appear in the order consistent with that shown above in the production for MethodModifier.
#1 Initializing a non static final variable with a literal:
class MyClass {
public final int ERROR_CODE = 200;
}
A bad practice since:
Each instance of the class will have a copy of this variable with the same value, since it's intended to be used as a global constant this is a waste of memory.
Static access to the constant is not possible, so MyClass.ERROR_CODE will not compile, if you just need this value you always need an instance e.g. new MyClass().ERROR_CODE
#2 Static variable
A static variable is useful in several cases, e.g. singleton patterns or class-related caches, or simply when you want to share some common data between all instances of the same class
#3 Yes
Maybe your class hasn’t gotten to this yet, but a class is an object, managed by a classloader. The classloader loads the class and makes sure there is only one class object. The class object is where static variables and methods live.
For #1, static means there is one variable that belongs to the class. The declaration without static means it is an instance variable, and every instance you create of that class has its own variable. For constants, make your variable static final so there is just one.
Final means the value doesn’t change. If the variable is a primitive then you can’t reassign the value. If the variable is a reference type then you can’t change what the variable points to. If the object pointed to is mutable itself, final doesn’t change that.
For 2, static variables belong to the class, one of your static methods can change what’s in the variable and other methods can see the change. Global mutable state is confusing to reason about, also you are leaving OO good practice behind and entering a domain of dirty hacks, so it’s a good idea to be very cautious about using this feature.
#3: come on you can try this out for yourself in about 10 seconds. Either way works. The google style guide advises “static final”.

Where to define constants in Java that are used in a couple of unrelated classes

The question of where to define constants in Java has appeared numerous times in forums, yet I am struggling to settle on a solution I feel comfortable with.
To make it simple, suppose I have two classes: WriteMyData and ReadMyData. None is a subclass of the other. Both classes share two constants that are vital for their operation: String DELIMITER and int LENGTH. In the future I might want to change the value of these constants so they should be defined somewhere appropriate.
The consensus seems to often favour the enum type. However, there is nothing to enumerate in my case, so I end up with only one item in my enum which I call DEFAULT:
public enum DataSettings {
DEFAULT(",", 32);
private final String delimiter;
private final int length;
DataSettings(String delmiter, int length) {
this.delimiter = delimiter;
this.length = length;
}
public String getDelimiter() { return delimiter; }
public int getLength() { return length; }
}
Thus, in both my classes I access the constants through DataSettings.DEFAULT.getDelimiter() and DataSettings.DEFAULT.getLength().
Is this really good OO style? Is the use of enum perhaps overkill? If I do not use enum, what should I do instead? Creating an interface for constants seems to be frowned upon, and there seems to be no natural superclass for my classes to derive from. Is it a beginners mistake to have only one default item in an enum?
Just create something like Constants.java class where you will put all the constants.
For example:
public class Constants {
public static final String DELIMITER = "-";
public static final int LENGTH = 1;
}
And use them where you want by:
Constants.DELIMITER
Constants.LENGTH
If only those two constans and not going to have more than that, You can have a Interface like
interface DataSetting
{
String DELIMITER = ",";
int LENGTH = 32;
}
And if you need to initilize through property
public class DataSetting {
public static String DELIMITER = ",";
public static int LENGTH = 32;
static {
DELIMITER = System.getProperty("delimiter");
LENGTH = Integer.parseInt(System.getProperty("length"));
// or from config
}
}
Using an enum when there is nothing to enumerate is indeed bad practice.
The other mentioned alternative, using an interface is also a poor choice. Effective Java, Item 19 describes it best:
Item19: Use interfaces only to define types
When a class implements an interface, the interface serves as a type that can be used to refer to instances of the class. That a class implements an interface should therefore say something about what a client can do with instances of the class. It is inappropriate to define an interface for any other purpose.
One kind of interface that fails this test is the so-called constant interface. Such an interface contains no methods; it consists solely of static final fields, each exporting a constant. Classes using these constants implement the interface to avoid the need to qualify constant names with a class name.
The correct implementation is to define a non-instantiable utility class:
public class Constants {
private Constants(){} // Private constructor prevents instantiation AND subclassing
public static final String DELIMITER = "-";
public static final int LENGTH = 1;
}
For convenience you can statically import the constants in your code:
import static com.example.Constants.*;
public class Test {
public static void main(String[] args){
System.out.println(DELIMITER); // prints "-"
}
}
An enumeration with just 1 value might not make much sense, although it might be useful if you plan on extending whatever values it could contain.
An alternative to what you are saying would be to do as follows:
Have a public class which exposes project-wide constants. You could make this class load it's values from some configuration file when your application is starting up so that you can control the values of these constants.
Have a separate set of methods suffixed with WithDefaultValues for your reading and writing methods. These methods will, in turn, call your other methods and pass in the default parameters.
As a side note, it might make sense to simply overload the methods you already have so that you have an implementation which defaults to these constants. If that is the case, be sure to document this in your method's signature.
IMO, Enum is overkill in this case. Enums are made for enumerations.
For global constants, you can just create a public static final class attribute in a java class or java interface, although the latest one is not the usual approach (see Interfaces with static fields in java for sharing 'constants')
I would propose another solution that doesn't use any constants in WriteMyData and ReadMyData.
Do pass delimiter and length as constructor parameters. This way you will be able to unit test these classes with parameters that may make testing more easy.
When it is important that an instance of each uses the same values for delimiter and length, then both should be instantiated at the same location and made available for clients to use. The location where the instances are created is a proper place to have constants for the values of delimiter and length.
You can create an interface.
By default constants in interface are static and final.
And you can user those variable by Referencing interface.
public interface AnyNameInterface {
String AnyVar ="DEMO";
Double AnyVar_2 = 123.00;
}
Use as:
AnyNameInterface.AnyVar
AnyNameInterface.AnyVar_2
I would like to add that even when there are something to enumerate, enums can't always be used as a container for constants, even though they are nice.
For instance, javax.ws.rs.Path defines a single annotation type element of type String. However, this won't compile:
#Path(MyEnum.BASE_PATH)
nor will
#Path(MyEnum.BASE_PATH.name())
Also, in those cases where it is not possible to define the constants on the class itself, or on some common superclass, the discussion often seem to be between defining the constants in a class vs in an interface. A third option could be to define them in an annotation.
public #interface MyAnnotation {
String QUESTIONS = "/questions";
String ANSWERS = "/answers"; }
The annotation approach steers clear of the "constant interface" pitfall. This pitfall is, in my understanding, not that the interface as a constant container in itself is a bad idea, - the problem is when callers decide to implement the interface, rather than accessing the constants through eg. a static import.

How to access individual values of an object that is stored in an array of similar objects in Java

I am having a problem with trying to keep my coding organized and as simple as possible. I basically have an array of similar objects that hold multiple values. I am wanting to access those individual values and be able to modify them at will but cannot seem to acess them. This is what the code basically looks like...
//In file Champion.java
package Champions;
public interface Champion{}
//In another file ChoGath.java
package Champions;
public class ChoGath implements Champion{
public static double health = 440.0;
}
//Yet another file Ahri.java
package Champions;
public class Ahri implements Champion{
public static double health = 380.0;
}
//In the main build file LOLChampBuilder.java
package LOLChampBuilder;
import Champions.*;
public class LOLChampBuilder{
public static Champion[] listOfChampions = {new ChoGath(), new Ahri()};
public static void main(String args[]){
//This next line works
System.out.println(new ChoGath().health);
//This next line does not work
System.out.println(listOfChampions[0].health);
}
}
There are more variables and whatnot but this is the basic problem.
ChoGath and Ahri are part of the group Champions and each has their own unique value for health. I want to be able to combine it all into an array for ease of grabbing values because I know where ChoGath (as an example) is in the array.
I get the error Cannot find symbol 'health' in Champions.Champion. I have gone and created the value in Champion and that fixes it (and also change it to class and then extends instead of implements) but then when I go to print the value is always 380.0 as it was the most recent edit to the value health in Champion.
I want it so that I can group all the "Champions" together under a single array (so they need to be the same object type ie: Champion, correct me if I'm wrong) and access their individual values. I cannot seem to do this so I don't know if I need to use ArrayList (which I've never used) or something else entirely. Now I know I could fix this and put it all into a massive file but I am trying to use multiple files for organizational purposes as well as cleanliness. Thoughts on what to do?
You need to add getHealth() to your interface. That's what getters are for.
Also avoid the use of static variables. They tend to produce programming errors.
You have to use getters and setters in the interface to get this functionality, or use a base class instead of an interface for Champion, e.g.:
interface Champion
{
public int getHealth();
public void setHealth(int health);
}
You need to have health variable in your interface. That is similar to concept of Subclass and Superclass. You can't access the variables of subclass using a superclass type because all superclass are not subclass(vice versa is true).You can only access them if its defined in the superclass. If you use a health variable in interface it has to be final static. So its better you use a setter and getter method in the interface to get the value.
interface Champion { public int getHealth(); }
Now implement this method in the ChoGath and Ahri classes

Java Code Static Final variable usage

I've got two classes below. Both have one variable 'reply' with a getter. There is no setter method for this variable. Only difference is in ClassOne, the variable is static final.
So whats the difference and which one is preferred?
public class ClassOne {
private static final String reply = "Success";
..
public String getReply() {
return reply;
}
// no setter
}
and Class 2
public class ClassTwo {
private String reply = "Success";
..
public String getReply() {
return reply;
}
// no setter
}
UPDATE 1:
What I want to know is that when there is no setter for a variable, should the variable be declared as static final for optimization? or does it not matter?
should the variable be declared as static final for optimization?
final certainly, not only for optimization but for clarity and because it can make your object immutable, which is always a good thing to have.
static completely changes the nature of the field and has nothing to do with the existence of setters: do you want only one instance of that field, or do you need one per instance of your class?
Non static example: a Person has a name, which is a constant (for a given person = per instance), so you can use a non static final field, which you only set once when creating a new Person:
private final String name;
Static example: Whenever you don't have a name for a Person, you want to use a default value - that is a global constant which is shared among all persons that don't have a name and you can use a static final field:
private static final String NO_NAME = "John Doe";
When you set the variable as final, you are telling everybody (the compiler, the runtime) that it cannot be changed. This can help a lot with optimizations like inlining all of the occurrences of the variable with its value.
When you have a constant string which can not be changed, you should make it a static final string.
Static means that less memory is needed for instance of the class, because the instances don't need individual copies.
Final allows some optimizations and thus makes your program faster.
There are few things good to know:
final variables can be checked by compiler that they are not accidentally changed.
references to non-static variables are contained in instance so there is small needless memory consumption in addition
static variables are shared across all instances of the same class, so you can be sure that all instances work with the same value
final static variables, especially the Strings are linked in compilation time so they need not to be dereferenced at runtime from the field. Due to that it cannot be changed even by the reflection, because such field is not used at runtime.
Setting the reference to final ensures you can't change the reference. Note however that if the object referred to is mutable then you could still change that (not in this instance, since Strings are immutable).
I normally make fields final and initialise them in the constructor. By favouring immutability my classes are easier to debug and are more likely to be safe in threaded environments. It's easier to remove the immutability constraint than add it.
I also do this for method arguments. Rarely (ever) do I want to change a method argument, and making them final will catch inadvertent assignments.
I try not to use static except for final constants. Unless it's something like a logger, I don't really want one instance per class, and (of course) this doesn't work in the case of multiple classloaders. It's also getting close to the singleton anti-pattern, and this impacts on easy testing and (potentially) threading.
The fact that you make the variable static means that a single instance of that variable will be shared among all the instances of ClassOne, as the variable is bound to the class itself, not to its instances. Apart from any JVM optimisations, you'll have a single instance of reply for every instance of ClassTwo.
First one is Constant you need to know value of it at compile time.
private static final String reply = "Success";
second is just simple member variable. So any case first one is preferred since second one will create value for each object.
Assuming that you intended **private final String reply** in second case
A final variable can only be initialized once, either via an initializer or an assignment statement. It does not need to be initialized at the point of declaration: this is called a "blank final" variable.
In second case you can also declare and initialize it in constructor
private final String reply;
You can read more about it here

Question about Java class

I am just learning Java as a hobby.
How do I make a class define a field? E.g.
private string[] biscuitlist
Thank you for any help provided.
Java is case sensitive. You need to declare it as String[], not as string[].
package yourpackage;
public class YourClass {
private String[] biscuitlist;
}
That said, this is actually not "subclassing". So your question title actually contradicts with the question message. To learn more about Java in general, I strongly recommend to go through the Trails Covering the Basics. Good luck.
The declaration goes inside the class definition as well.
public class SomeClass {
private String[] biscuitlist; // declare the variable
public SomeClass(){} // empty constructor
public String[] getList() {
// the variable is private so provide a getter for external access
return biscuitList;
}
}
If you declare the variable private only methods inside the class can access it. Checkout access controls to understand this if you need to.
You have defined variable already. Just note,
Java is case sensitive.
All classes starts uppercase, e.g. String, Date, List, etc by convention.
A class is basically a set of data (fields) and a bunch of operations(methods) on those fields
public class yourClass{
//define fields here
private String[] biscuitlist;
// java will automagically set biscuitlist to a null reference
//make a constructor for your class if it will ever be instantiated
public yourClass(){
}
//do stuff here (methods)
}
So basically defining a field is as simple as typing in the access(public, private, protected) giving it a type (String, int, String[], Object) and giving it a name. if not assigned a value after they will default based on the java API (objects get a null reference, ints get 0 etc.)

Categories