Despite Java tutorials, Wikipedia searches, stackoverflow trolling, and hours of reading code samples, constructors still confuse the crap out of me. I've got three related questions that I've been trying to answer to help ME understand constructors a little better.
First, I've been under the impression that constructors need to be named the same as their classes. Consider:
public class Money {
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
public long getLong() {
return this.value;
}
public String getString() {
return toString(this.value);
}
}
I see this as four constructors...correct? So it appears that constructors not named the same as the class which contains them allowable. Can someone confirm that?
Second, I seem to have a block against understanding the set and get methods. Consider:
public class GetSetSample {
public int getFoo() {
return int Foo;
}
public void setFoo(int fooValue) {
int Foo = fooValue;
}
}
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
and use foo = getFoo(12) from some other class/method?
The third question is a little more esoteric, but will help me conceive of the bigger picture...which is my learning style, and conducive to my ability to trace program flow when debugging. The get and set methods suggest a "to" and "from" relationship to me. e.g., Passing a value "to" a constructor, receiving the result "from" the get method. It seems to me though that the "to" and "from" will change depending on your perspective. I think that any setMethod is setting parameters for an object, even though the variable comes FROM another class or method, and the GetMethod is getting the resulting object (say, this.foo) with the appropriately set parameter. No matter where the get or set is used, in a main method or a standalone class with a single constructor, 'set' is always associated with sending a parameter and get is always associated with receiving an object with that parameter. Is that a good understanding? or am I missing a vital part?
Question 1:
I see this as four constructors...correct?
No, that class has two constructors and two methods. (getLong and getString are the methods.)
Question 2:
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
Well, that's trying to declare a class with parameters, and also you're setting a value in a get method, which would be extremely weird. It's not clear what you're trying to achieve here, but that code is thoroughly invalid.
Question 3:
The get and set methods suggest a "to" and "from" relationship to me.
Well it's not really a relationship IMO. A relationship suggests something longer term than either of these methods. A setter typically changes the state of an object in some way, and a getter typically just returns some aspect of the state of an object. It's not really clear what the rest of your explanation meant, because you're playing somewhat fast and loose with terminology. For example: "get is always associated with receiving an object with that parameter" doesn't really make sense to me. Objects don't have parameters, methods/constructors do - and getters can fetch primitive values or references...
I suspect you would benefit from reading the "Classes" part of the Java tutorial, which talks about constructors and methods.
Regarding the first answer, there's only 2 constructors. The difference is on how they are going to be called (called using a string will use the construction having a string has a parameter and called using a long will use the other one). So to answer, yes a constructor has the same name as the class.
The two constructors :
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
Regarding the second answer, getters ans setters are not meant to be classes. They are supposed to be within the class itself.
Consider this example which uses getter and setters to get ans set value for the printer class :
public class Printer {
#Inject #Informal Greeting greeting;
private String name;
private String salutation;
public void createSalutation() {
this.salutation = greeting.greet(name);
}
public String getSalutation() {
return salutation;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
A good read of this link could definitly help you out !
Java oriented-object principles
You've shown 2 constructors, which do need to have the same name as the class.
You've also shown two "getter" methods, which return the value of the class variable in the form requested by the user. You can also create "setter" methods, which are used to transfer values into class variables.
You use a constructor to create an object of a particular class, and optionally to set some or all of its internal state (that is, its member variables).
You use setters and getters to isolate the class variables from the outside world, so you don't need to allow other code to access them directly. Why? Because, before a setter updates a variable, it can verify that the new value is valid, and that the operation doesn't violate any or the rules (the "business logic") that are required for the class to work properly.
So you could add a setter and update the constructor to use it:
public Money(long l) {
setValue(l);
}
public Money(String s) {
setValue(toLong(s));
}
// Example setter that validates `l` by prohibiting negative values
public Money setValue(long l) {
if (l < 0) {
// Warn about negative values
}
this.value = l;
return this; // Return the current object to allow chaining; see below.
}
Note that a setter usually doesn't need to return a value (that is, it can be type void), but it's often helpful to return the object itself. That allows you to write code like this:
Money earnings = new Money().setValue(4).setOtherField("foo");
This creates an object of type Money, sets various attributes, and stores it in the variable earnings. Clearly, this isn't terribly useful for a simple class like this, but it can be very helpful for more complex classes:
Paycheck check = new Paycheck("MyCompany")
.setEmployee("YourName")
.setSalary(50,000)
.setPaySchedule(Schedule.BIWEEKLY)
.setAccountNumber("1234567")
.setDefaultTaxRate();
I would like to try to answer your implied conceptual questions -- you've already got plenty of examples of this and that, so I'm just going to try to explain. I have no doubt you have heard most of this -- maybe all of this -- before, but am not sure and not sure which parts.
Object-oriented programming centers mostly around objects; an object is an amalgamation of code and data. You define objects by writing a class, and you create one or more copies of the object defined by that class with the class constructor (called instantiating the class).
A parallel in other languages: you can have a data structure of related items and a set of subroutines that operate on that data structure. Think of a class as a way of collecting the items in that data structure and the subroutines that operate on it into one unit.
After you have invoked a constructor, you have a copy of the data defined in that class and a way to refer to that copy. By referring to that instance when you invoke a class method, you operate on that copy of the data with the methods defined in that class.
If you were to do this in a non-OO language, you could have a routine that created a copy of the data structure in memory and then only use the methods prescribed for it on that data structure. You could have a pointer to the copy in memory and pass that pointer as a parameter to every subroutine that operated on it, and in fact that's the way some pre-OO systems were programmed.
A constructor is similar to a method call that returns a value; it involves (or can involve) the execution of statements, and it always returns an object of that class. There are also differences between a constructor and a method; until the constructor completes, for instance, the object is not fully created and shouldn't have some methods invoked on it.
So I hope that helped; if there are conceptual things you still have questions about, perhaps something in here will help you form a specific question so we can explain things further.
Many people have found that if they have spent years learning languages such as COBOL and FORTRAN then changing to OO programming involves unlearning the old languages. I certainly found this when I first tackled C++ 20 years ago. From your description you are clearly struggling with the concepts and I sympathize.
I don't think there is a simple recipe. Practice at the simple examples and don't be disheartened. Don't be afraid to ask on SO - if the questions are clearly asked you will get a useful answer.
Get a good IDE (Eclipse, Netbeans, etc.) which allows you to "look inside" objects with the debugger. Hopefully at some stage things will click!
Question 1 - Basic Java Classes:
There's pretty much only 3 things you're going to find in a Java class
Field/attribute (Depending on your language of origin)
Method
Constructor (Which looks like a special kind of method)
Every class is going to have a class name that shares the name of the file it's located in. So to expand Money out a bit:
Money.java
----------
public class Money {
// This is a field/attribute
Long value;
// This is a constructor
public Money() {
this.value = Long(0L);
}
// This is a method
public Long getValue() {
return value;
}
// Another method
public void makeMoney(Long moreMoney) {
this.value = this.value + moreMoney;
}
} // Everything in here is part of the Money class
The only distinction between a constructor and a method is that a constructor has no specified return value, which is declared as a type right before the name of a potential method. Constructors do have to be named the same as the class they are contained in, but why is implied in how they are written.
Another way of looking at it is if you remove all of the non-type related Java keywords (public, private etc., but not things like float and int) from the front of the method you're looking at (A list of which you can find here), is there anything left in front of the method?
With the Money we have at the moment, it would look like this:
Money()
Long getValue()
void makeMoney()
The constructor is the one that has no type for the return value, because it is implied in the declaration.
Question 2/3 - Get/Set methods:
I'm going to say something potentially controversial, but don't worry about these yet. Get/Set are essentially patterns for Object Oriented development, and generally good Java style, but they aren't required (Last I checked, Android development actually discourages their use when possible for optimization reasons). Moreover, not all fields in your objects will be accessible or mutable so writing them isn't mandatory.
If you declare all of your fields as public (Like the 'value' field is implied to be right now), you simple can do this:
Money myMoney = new Money(new Long(40L));
System.out.println(myMoney.value) // 40
myMoney.value = new Long(20L);
System.out.println(myMoney.value) // 20
Aside from that, the notion of get() and set() are just methods. There is nothing special about them at all. The main reason they exist is because for general Object-Oriented programming, you shouldn't have to directly modify the internal workings of an object (This is the principle of Encapsulation). Everything you should need to affect state or get something out of it should be handled by a method.
In a pithy one-liner: If you need to know the fields of an object to use it, you designed it incorrectly.
Big Picture
So what get() and set() really are is a pair of commonly written methods that happen to affect a field in an object in an extremely simple way (get() is a simple access to a field, set() is assignment to that field). It's just that other methods you write will happen to do more complicated stuff than that.
I have the code of a simple game, where an AgentInterface must be implemented in order to create an agent controller for one of the characters in the game. GameState is a class the implements GameStateInterface, and an object that implements this interface can be passed to the agent, so the agent can read and analyze the data from game state, and the agent must return the appropriate action (returned as an int) that the character should take.
This is the AgentInterface that agents must implement:
public interface AgentInterface {
// the return value specifies the direction of the joystick
public int action(GameStateInterface gs);
}
Running the game with an agent called MyAgent:
GameState gs = new GameState();
AgentInterface agent = new MyAgent();
while (true) {
// more code here
int bestAction = agent.action(gs)
// more code here
}
But, there is some information in GameState that the agent should NOT be able to access, since that would be cheating for the controller. But, doing a cast conversion from GameStateInterface to GameState would allow the agent to access information that is not defined in the GameStateInterface, like this:
public MyAgent implements AgentInterface {
public int action(GameStateInterface gs) {
int nLives = ((GameState) gs).nLivesRemaining; // IS IT POSSIBLE TO DENY/PREVENT THIS CAST??
// Do more stuff here
return BestAction;
}
}
My question would be, is it possible to block a cast conversion? I know polymorphism is one of the main features of Java and Object-Oriented Programming Languages, but in cases like this I would like to avoid cast conversions.
I know this can be solved in many other ways, but I was curious to know if it is possible to do this.
Thanks in advance.
As far as I know, it's not possible to intercept a typecast and deny it (say, by throwing a ClassCastException).
But instead of trying to deny the typecase, you can simply use the Proxy pattern to control access to the actual GameState object. Just implement a proxy class, which only implements the GameStateInterface and let it forward all method calls to the GameState object. Now, instead of passing the actual GameState object reference to the action method, you pass it wrapped by an instance of your proxy class.
In general, you can't prevent an object from being cast in Java. The code that receives a reference to your GameState will be able to call any non-private, non-protected method on that object. Even if you could prevent casting, it could still use reflection.
If the Agent code is under your control, just keep things simple and don't cast. If others write Agent classes, you could create a proxy class which takes a GameState object and only implements the methods of GameStateInterface.
class GameStateProxy implements GameStateInterface {
private GameStateInterface state;
public GameStateProxy(GameState state) {
this.state = state;
}
public int someMethodInGameStateInterface(int x) {
return state.someMethodInGameStateInterface(x);
}
// other methods ...
}
Then you could create a proxy and pass it like this:
GameStateInterface proxy = new GameStateProxy(gameState);
int bestAction = agent.action(proxy);
The code that receives a GameStateProxy would only have access to the methods in GameStateInterface.
It's not possible to block a cast. However, you could define your game state in such a way that it can only be built from a specific place. One thing that comes to mind would be a private inner class implementing the interface, or a factory returning a private inner class instance
The answer is simply "don't cast to GameState in your Agent code".
Alternatively, you can declare the GameState stuff as private. Or if you need to access it from a select few other classes, declare it as package-protected.
If you are concerned about the game state being changed by an agent, then create a bean copy of the state and pass that to the agent, rather than the real GameState object.
Prohibiting a cast doesn't sound possible (it is probably a unblockable JVM language spec feature), or I have never heard of it.
I was implementing a secured read only object. If you create a read only interface (no setters) you still can typecast and access methods of pure object. Eg Interface have only a get and the child of this Interface have the set. If you cast the object to the interface, you only have the get. BUT you still can typecast this object and access everything :(
To avoid that, you can create a composite that will be owned ONLY by the creator of the class. Here is an example :
public class ItemReadOnly {
private String m_name;
private ItemReadOnly(String name){
m_name = name;
}
public String getName(){
return m_name;
}
private void setName(String name){
m_name = name;
}
public static Item createItem(String name){
return new Item(new ItemReadOnly(name));
}
private static class Item {
private ItemReadOnly m_readOnlyInstance;
public Item(ItemReadOnly readOnlyInstance){
m_readOnlyInstance = readOnlyInstance;
}
public void setName(String name){
m_readOnlyInstance.setName(name);
}
public String getName(){
return m_readOnlyInstance.getName();
}
public ItemReadOnly getReadOnlyInstance(){
return m_readOnlyInstance;
}
}
}
This way, you type :
Item item = ItemReadOnly.createItem(name);
So he have the access of Item object (inner class can access private methods :)) Then if you want to give read only access to this item :
ItemReadOnly readOnly = item.getReadOnlyInstance();
Now, it's absolutely NOT possible to typecast because they are not of the same type at all!
Hope this can help someone!
(I'll like if you mention source :P)
What we do is give out a jar with "Stubs" that you can compile against but it contains no implementation. When the actual product runs, we replace the stubs with a real jar.
But then in our case, we control where it runs.
In our case, also, we do exactly what you are asking. Any class has to request access to other classes (at runtime). I believe that's all custom implementation though and I'm not sure it will run on any JVM.
You can try to find/request/whatever the source code for the stuff I'm working on. There is a reference implementation available if you say you are interested in developing for cable boxes you might be able to get it. It's called the "tru2way" or "OCAP" reference stack implementation and I think the project is available on the java site somewhere. Might take a bit of googling--and I'm fairly sure you'll find it's all done in a special class loader or SecurityManager.
EDIT: I think I may be wrong. What we do is create "permissions" with the security manager based on the name of the class being accessed. When a thread tries to call a method on the class, we test it's permissions first (we write the code inside the "protected" class) and if the current thread does not have the permission identified by the name of the class, it throws an exception.
Same effect as you are after, but slower and more verbose. But then we have to prevent kids from watching pr0n.
Edit 2: (Sorry!!)
Looking at permission descriptions like this makes me believe it must be at least partially possible:
This grants code permission to query a class for its public, protected, default (package) access, and private fields and/or methods. Although the code would have access to the private and protected field and method names, it would not have access to the private/protected field data and would not be able to invoke any private methods. Nevertheless, malicious code may use this information to better aim an attack. Additionally, it may invoke any public methods and/or access public fields in the class. This could be dangerous if the code would normally not be able to invoke those methods and/or access the fields because it can't cast the object to the class/interface with those methods and fields.
Otherwise how could applets be prevented from instantiating and accessing arbitrary JVM classes? It's possible that the "Dangerous" paths are all blocked the same way we block our stuff--by reading checking permissions every time they are called--but that quote above makes it seem like there is more available and most classes are completely blocked by default.
This has interested me for a while but I never really looked into it.
One can only cast to an accessible type. By making GameState private, package-protected, or protected, you can restrict who can cast to it.
If you are running untrusted code, be sure to install a security manager, as reflection may be used to circumvent access modifiers in its absensce (c.f. Field.setAccessible)
Nope, there is no way of doing this.
Best wishes,
Fabian
I don't know if what you're describing is possible in Java. In other languages you can overload typecast operators and have them throw an exception or something, but this is not possible in Java. Your best bet is probably to do it in one of the "many other ways" you talked about.
Closed. This question is opinion-based. It is not currently accepting answers.
Closed 5 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I've seen examples like this:
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
and supposed that I could have a Constants class to wrap constants in, declaring them static final. I know practically no Java at all and am wondering if this is the best way to create constants.
That is perfectly acceptable, probably even the standard.
(public/private) static final TYPE NAME = VALUE;
where TYPE is the type, NAME is the name in all caps with underscores for spaces, and VALUE is the constant value;
I highly recommend NOT putting your constants in their own classes or interfaces.
As a side note: Variables that are declared final and are mutable can still be changed; however, the variable can never point at a different object.
For example:
public static final Point ORIGIN = new Point(0,0);
public static void main(String[] args){
ORIGIN.x = 3;
}
That is legal and ORIGIN would then be a point at (3, 0).
I would highly advise against having a single constants class. It may seem a good idea at the time, but when developers refuse to document constants and the class grows to encompass upwards of 500 constants which are all not related to each other at all (being related to entirely different aspects of the application), this generally turns into the constants file being completely unreadable. Instead:
If you have access to Java 5+, use enums to define your specific constants for an application area. All parts of the application area should refer to enums, not constant values, for these constants. You may declare an enum similar to how you declare a class. Enums are perhaps the most (and, arguably, only) useful feature of Java 5+.
If you have constants that are only valid to a particular class or one of its subclasses, declare them as either protected or public and place them on the top class in the hierarchy. This way, the subclasses can access these constant values (and if other classes access them via public, the constants aren't only valid to a particular class...which means that the external classes using this constant may be too tightly coupled to the class containing the constant)
If you have an interface with behavior defined, but returned values or argument values should be particular, it is perfectly acceptible to define constants on that interface so that other implementors will have access to them. However, avoid creating an interface just to hold constants: it can become just as bad as a class created just to hold constants.
It is a BAD PRACTICE to use interfaces just to hold constants (named constant interface pattern by Josh Bloch). Here's what Josh advises:
If the constants are strongly tied to
an existing class or interface, you
should add them to the class or
interface. For example, all of the
boxed numerical primitive classes,
such as Integer and Double, export
MIN_VALUE and MAX_VALUE constants. If
the constants are best viewed as
members of an enumerated type, you
should export them with an enum
type. Otherwise, you should export the
constants with a noninstantiable
utility class.
Example:
// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
private PhysicalConstants() { } // Prevents instantiation
public static final double AVOGADROS_NUMBER = 6.02214199e23;
public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
public static final double ELECTRON_MASS = 9.10938188e-31;
}
About the naming convention:
By convention, such fields have names
consisting of capital letters, with
words separated by underscores. It is
critical that these fields contain
either primitive values or references
to immutable objects.
In Effective Java (2nd edition), it's recommended that you use enums instead of static ints for constants.
There's a good writeup on enums in Java here:
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
Note that at the end of that article the question posed is:
So when should you use enums?
With an answer of:
Any time you need a fixed set of constants
Just avoid using an interface:
public interface MyConstants {
String CONSTANT_ONE = "foo";
}
public class NeddsConstant implements MyConstants {
}
It is tempting, but violates encapsulation and blurs the distinction of class definitions.
I use following approach:
public final class Constants {
public final class File {
public static final int MIN_ROWS = 1;
public static final int MAX_ROWS = 1000;
private File() {}
}
public final class DB {
public static final String name = "oups";
public final class Connection {
public static final String URL = "jdbc:tra-ta-ta";
public static final String USER = "testUser";
public static final String PASSWORD = "testPassword";
private Connection() {}
}
private DB() {}
}
private Constants() {}
}
Than, for example, I use Constants.DB.Connection.URL to get constant.
It looks more "object oriently" as for me.
Creating static final constants in a separate class can get you into trouble. The Java compiler will actually optimize this and place the actual value of the constant into any class that references it.
If you later change the 'Constants' class and you don't do a hard re-compile on other classes that reference that class, you will wind up with a combination of old and new values being used.
Instead of thinking of these as constants, think of them as configuration parameters and create a class to manage them. Have the values be non-final, and even consider using getters. In the future, as you determine that some of these parameters actually should be configurable by the user or administrator, it will be much easier to do.
The number one mistake you can make is creating a globally accessible class called with a generic name, like Constants. This simply gets littered with garbage and you lose all ability to figure out what portion of your system uses these constants.
Instead, constants should go into the class which "owns" them. Do you have a constant called TIMEOUT? It should probably go into your Communications() or Connection() class. MAX_BAD_LOGINS_PER_HOUR? Goes into User(). And so on and so forth.
The other possible use is Java .properties files when "constants" can be defined at run-time, but not easily user changeable. You can package these up in your .jars and reference them with the Class resourceLoader.
That's the right way to go.
Generally constants are not kept in separate "Constants" classes because they're not discoverable. If the constant is relevant to the current class, keeping them there helps the next developer.
What about an enumeration?
I prefer to use getters rather than constants. Those getters might return constant values, e.g. public int getMaxConnections() {return 10;}, but anything that needs the constant will go through a getter.
One benefit is that if your program outgrows the constant--you find that it needs to be configurable--you can just change how the getter returns the constant.
The other benefit is that in order to modify the constant you don't have to recompile everything that uses it. When you reference a static final field, the value of that constant is compiled into any bytecode that references it.
I agree that using an interface is not the way to go. Avoiding this pattern even has its own item (#18) in Bloch's Effective Java.
An argument Bloch makes against the constant interface pattern is that use of constants is an implementation detail, but implementing an interface to use them exposes that implementation detail in your exported API.
The public|private static final TYPE NAME = VALUE; pattern is a good way of declaring a constant. Personally, I think it's better to avoid making a separate class to house all of your constants, but I've never seen a reason not to do this, other than personal preference and style.
If your constants can be well-modeled as an enumeration, consider the enum structure available in 1.5 or later.
If you're using a version earlier than 1.5, you can still pull off typesafe enumerations by using normal Java classes. (See this site for more on that).
Based on the comments above I think this is a good approach to change the old-fashioned global constant class (having public static final variables) to its enum-like equivalent in a way like this:
public class Constants {
private Constants() {
throw new AssertionError();
}
public interface ConstantType {}
public enum StringConstant implements ConstantType {
DB_HOST("localhost");
// other String constants come here
private String value;
private StringConstant(String value) {
this.value = value;
}
public String value() {
return value;
}
}
public enum IntConstant implements ConstantType {
DB_PORT(3128),
MAX_PAGE_SIZE(100);
// other int constants come here
private int value;
private IntConstant(int value) {
this.value = value;
}
public int value() {
return value;
}
}
public enum SimpleConstant implements ConstantType {
STATE_INIT,
STATE_START,
STATE_END;
}
}
So then I can refer them to like:
Constants.StringConstant.DB_HOST
A good object oriented design should not need many publicly available constants. Most constants should be encapsulated in the class that needs them to do its job.
There is a certain amount of opinion to answer this. To start with, constants in java are generally declared to be public, static and final. Below are the reasons:
public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
makes little sense to duplicate them for every object.
final, since they should not be allowed to change
I would never use an interface for a CONSTANTS accessor/object simply because interfaces are generally expected to be implemented. Wouldn't this look funny:
String myConstant = IMyInterface.CONSTANTX;
Instead I would choose between a few different ways, based on some small trade-offs, and so it depends on what you need:
1. Use a regular enum with a default/private constructor. Most people would define
constants this way, IMHO.
- drawback: cannot effectively Javadoc each constant member
- advantage: var members are implicitly public, static, and final
- advantage: type-safe
- provides "a limited constructor" in a special way that only takes args which match
predefined 'public static final' keys, thus limiting what you can pass to the
constructor
2. Use a altered enum WITHOUT a constructor, having all variables defined with
prefixed 'public static final' .
- looks funny just having a floating semi-colon in the code
- advantage: you can JavaDoc each variable with an explanation
- drawback: you still have to put explicit 'public static final' before each variable
- drawback: not type-safe
- no 'limited constructor'
3. Use a Class with a private constructor:
- advantage: you can JavaDoc each variable with an explanation
- drawback: you have to put explicit 'public static final' before each variable
- you have the option of having a constructor to create an instance
of the class if you want to provide additional functions related
to your constants
(or just keep the constructor private)
- drawback: not type-safe
4. Using interface:
- advantage: you can JavaDoc each variable with an explanation
- advantage: var members are implicitly 'public static final'
- you are able to define default interface methods if you want to provide additional
functions related to your constants (only if you implement the interface)
- drawback: not type-safe
What is the best way to implement constants in Java?
One approach that we should really avoid : using interfaces to define constants.
Creating a interface specifically to declare constants is really the worst thing : it defeats the reason why interfaces were designed : defining method(s) contract.
Even if an interface already exists to address a specific need, declaring the constants in them make really not sense as constants should not make part of the API and the contract provided to client classes.
To simplify, we have broadly 4 valid approaches.
With static final String/Integer field :
1) using a class that declares constants inside but not only.
1 variant) creating a class dedicated to only declare constants.
With Java 5 enum :
2) declaring the enum in a related purpose class (so as a nested class).
2 variant) creating the enum as a standalone class (so defined in its own class file).
TLDR : Which is the best way and where locate the constants ?
In most of cases, the enum way is probably finer than the static final String/Integer way and personally I think that the static final String/Integer way should be used only if we have good reasons to not use enums.
And about where we should declare the constant values, the idea is to search whether there is a single existing class that owns a specific and strong functional cohesion with constant values. If we find such a class, we should use it as the constants holder. Otherwise, the constant should be associated to no one particular class.
static final String/ static final Integer versus enum
Enums usage is really a way to strongly considered.
Enums have a great advantage over String or Integer constant field.
They set a stronger compilation constraint.
If you define a method that takes the enum as parameter, you can only pass a enum value defined in the enum class(or null).
With String and Integer you can substitute them with any values of compatible type and the compilation will be fine even if the value is not a defined constant in the static final String/ static final Integer fields.
For example, below two constants defined in a class as static final String fields :
public class MyClass{
public static final String ONE_CONSTANT = "value";
public static final String ANOTHER_CONSTANT = "other value";
. . .
}
Here a method that expects to have one of these constants as parameter :
public void process(String constantExpected){
...
}
You can invoke it in this way :
process(MyClass.ONE_CONSTANT);
or
process(MyClass.ANOTHER_CONSTANT);
But no compilation constraint prevents you from invoking it in this way :
process("a not defined constant value");
You would have the error only at runtime and only if you do at a time a check on the transmitted value.
With enum, checks are not required as the client could only pass a enum value in a enum parameter.
For example, here two values defined in a enum class (so constant out of the box):
public enum MyEnum {
ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");
private String value;
MyEnum(String value) {
this.value = value;
}
...
}
Here a method that expects to have one of these enum values as parameter :
public void process(MyEnum myEnum){
...
}
You can invoke it in this way :
process(MyEnum.ONE_CONSTANT);
or
process(MyEnum.ANOTHER_CONSTANT);
But the compilation will never allow you from invoking it in this way :
process("a not defined constant value");
Where should we declare the constants ?
If your application contains a single existing class that owns a specific and strong functional cohesion with the constant values, the 1) and the 2) appear more intuitive.
Generally, it eases the use of the constants if these are declared in the main class that manipulates them or that has a name very natural to guess that we will find it inside.
For example in the JDK library, the exponential and pi constant values are declared in a class that declare not only constant declarations (java.lang.Math).
public final class Math {
...
public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;
...
}
The clients using mathematics functions rely often on the Math class.
So, they may find constants easily enough and can also remember where E and PI are defined in a very natural way.
If your application doesn't contain an existing class that has a very specific and strong functional cohesion with the constant values, the 1 variant) and the 2 variant) ways appear more intuitive.
Generally, it doesn't ease the use of the constants if these are declared in one class that manipulates them while we have also 3 or 4 other classes that manipulate them as much as and no one of these classes seems be more natural than others to host constant values.
Here, defining a custom class to hold only constant values makes sense.
For example in the JDK library, the java.util.concurrent.TimeUnit enum is not declared in a specific class as there is not really one and only one JDK specific class that appear as the most intuitive to hold it :
public enum TimeUnit {
NANOSECONDS {
.....
},
MICROSECONDS {
.....
},
MILLISECONDS {
.....
},
SECONDS {
.....
},
.....
}
Many classes declared in java.util.concurrent use them :
BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService , ... and really no one of them seems more appropriate to hold the enum.
A Constant, of any type, can be declared by creating an immutable property that within a class (that is a member variable with the final modifier). Typically the static and public modifiers are also provided.
public class OfficePrinter {
public static final String STATE = "Ready";
}
There are numerous applications where a constant's value indicates a selection from an n-tuple (e.g. enumeration) of choices. In our example, we can choose to define an Enumerated Type that will restrict the possible assigned values (i.e. improved type-safety):
public class OfficePrinter {
public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
public static final PrinterState STATE = PrinterState.Ready;
}
A single, generic constants class is a bad idea. Constants should be grouped together with the class they're most logically related to.
Rather than using variables of any kind (especially enums), I would suggest that you use methods. Create a method with the same name as the variable and have it return the value you assigned to the variable. Now delete the variable and replace all references to it with calls to the method you just created. If you feel that the constant is generic enough that you shouldn't have to create an instance of the class just to use it, then make the constant method a class method.
FWIW, a timeout in seconds value should probably be a configuration setting (read in from a properties file or through injection as in Spring) and not a constant.
What is the difference
1.
public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}
2.
public class MyGlobalConstants {
private MyGlobalConstants () {} // Prevents instantiation
public static final int TIMEOUT_IN_SECS = 25;
}
and using
MyGlobalConstants.TIMEOUT_IN_SECS wherever we need this constant. I think both are same.
I wouldn't call the class the same (aside from casing) as the constant ... I would have at a minimum one class of "Settings", or "Values", or "Constants", where all the constants would live. If I have a large number of them, I'd group them up in logical constant classes (UserSettings, AppSettings, etc.)
To take it a step further, you can place globally used constants in an interface so they can be used system wide. E.g.
public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}
But don't then implement it. Just refer to them directly in code via the fully qualified classname.
For Constants, Enum is a better choice IMHO. Here is an example
public class myClass {
public enum myEnum {
Option1("String1", 2),
Option2("String2", 2)
;
String str;
int i;
myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }
}
One of the way I do it is by creating a 'Global' class with the constant values and do a static import in the classes that need access to the constant.
static final is my preference, I'd only use an enum if the item was indeed enumerable.
I use static final to declare constants and go with the ALL_CAPS naming notation. I have seen quite a few real life instances where all constants are bunched together into an interface. A few posts have rightly called that a bad practice, primarily because that's not what an interface is for. An interface should enforce a contract and should not be a place to put unrelated constants in. Putting it together into a class that cannot be instantiated (through a private constructor) too is fine if the constant semantics don't belong to a specific class(es). I always put a constant in the class that it's most related to, because that makes sense and is also easily maintainable.
Enums are a good choice to represent a range of values, but if you are storing standalone constants with an emphasis on the absolute value (eg. TIMEOUT = 100 ms) you can just go for the static final approach.
I agree with what most are saying, it is best to use enums when dealing with a collection of constants. However, if you are programming in Android there is a better solution: IntDef Annotation.
#Retention(SOURCE)
#IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public #interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(#NavigationMode int mode);
#NavigationMode
public abstract int getNavigationMode();
IntDef annotation is superior to enums in one simple way, it takes significantly less space as it is simply a compile-time marker. It is not a class, nor does it have the automatic string-conversion property.
It is BAD habit and terribly
ANNOYING practice to quote Joshua Bloch without understanding the basic ground-zero fundamentalism.
I have not read anything Joshua Bloch, so either
he is a terrible programmer
or the people so far whom I find quoting him (Joshua is the name of a boy I presume) are simply using his material as religious scripts to justify their software religious indulgences.
As in Bible fundamentalism all the biblical laws can be summed up by
Love the Fundamental Identity with all your heart and all your mind
Love your neighbour as yourself
and so similarly software engineering fundamentalism can be summed up by
devote yourself to the ground-zero fundamentals with all your programming might and mind
and devote towards the excellence of your fellow-programmers as you would for yourself.
Also, among biblical fundamentalist circles a strong and reasonable corollary is drawn
First love yourself. Because if you don't love yourself much, then the concept "love your neighbour as yourself" doesn't carry much weight, since "how much you love yourself" is the datum line above which you would love others.
Similarly, if you do not respect yourself as a programmer and just accept the pronouncements and prophecies of some programming guru-nath WITHOUT questioning the fundamentals, your quotations and reliance on Joshua Bloch (and the like) is meaningless. And therefore, you would actually have no respect for your fellow-programmers.
The fundamental laws of software programming
laziness is the virtue of a good programmer
you are to make your programming life as easy, as lazy and therefore as effective as possible
you are to make the consequences and entrails of your programming as easy, as lazy and therefore as effective as possible for your neigbour-programmers who work with you and pick up your programming entrails.
Interface-pattern constants is a bad habit ???
Under what laws of fundamentally effective and responsible programming does this religious edict fall into ?
Just read the wikipedia article on interface-pattern constants (https://en.wikipedia.org/wiki/Constant_interface), and the silly excuses it states against interface-pattern constants.
Whatif-No IDE? Who on earth as a software programmer would not use an IDE? Most of us are programmers who prefer not to have to prove having macho aescetic survivalisticism thro avoiding the use of an IDE.
Also - wait a second proponents of micro-functional programming as a means of not needing an IDE. Wait till you read my explanation on data-model normalization.
Pollutes the namespace with variables not used within the current scope? It could be proponents of this opinion
are not aware of, and the need for, data-model normalization
Using interfaces for enforcing constants is an abuse of interfaces. Proponents of such have a bad habit of
not seeing that "constants" must be treated as contract. And interfaces are used for enforcing or projecting compliance to a contract.
It is difficult if not impossible to convert interfaces into implemented classes in the future. Hah .... hmmm ... ???
Why would you want to engage in such pattern of programming as your persistent livelihood? IOW, why devote yourself to such an AMBIVALENT and bad programming habit ?
Whatever the excuses, there is NO VALID EXCUSE when it comes to FUNDAMENTALLY EFFECTIVE software engineering to delegitimize or generally discourage the use of interface constants.
It doesn't matter what the original intents and mental states of the founding fathers who crafted the United States Constitution were. We could debate the original intents of the founding fathers but all I care is the written statements of the US Constitution. And it is the responsibility of every US citizen to exploit the written literary-fundamentalism, not the unwritten founding-intents, of the US Constitution.
Similarly, I do not care what the "original" intents of the founders of the Java platform and programming language had for the interface. What I care are the effective features the Java specification provides, and I intend to exploit those features to the fullest to help me fulfill the fundamental laws of responsible software programming. I don't care if I am perceived to "violate the intention for interfaces". I don't care what Gosling or someone Bloch says about the "proper way to use Java", unless what they say does not violate my need to EFFECTIVE fulfilling fundamentals.
The Fundamental is Data-Model Normalization
It doesn't matter how your data-model is hosted or transmitted. Whether you use interfaces or enums or whatevernots, relational or no-SQL, if you don't understand the need and process of data-model normalization.
We must first define and normalize the data-model of a set of processes. And when we have a coherent data-model, ONLY then can we use the process flow of its components to define the functional behaviour and process blocks a field or realm of applications. And only then can we define the API of each functional process.
Even the facets of data normalization as proposed by EF Codd is now severely challenged and severely-challenged. e.g. his statement on 1NF has been criticized as ambiguous, misaligned and over-simplified, as is the rest of his statements especially in the advent of modern data services, repo-technology and transmission. IMO, the EF Codd statements should be completely ditched and new set of more mathematically plausible statements be designed.
A glaring flaw of EF Codd's and the cause of its misalignment to effective human comprehension is his belief that humanly perceivable multi-dimensional, mutable-dimension data can be efficiently perceived thro a set of piecemeal 2-dimensional mappings.
The Fundamentals of Data Normalization
What EF Codd failed to express.
Within each coherent data-model, these are the sequential graduated order of data-model coherence to achieve.
The Unity and Identity of data instances.
design the granularity of each data component, whereby their granularity is at a level where each instance of a component can be uniquely identified and retrieved.
absence of instance aliasing. i.e., no means exist whereby an identification produces more than one instance of a component.
Absence of instance crosstalk. There does not exist the necessity to use one or more other instances of a component to contribute to identifying an instance of a component.
The unity and identity of data components/dimensions.
Presence of component de-aliasing. There must exist one definition whereby a component/dimension can be uniquely identified. Which is the primary definition of a component;
where the primary definition will not result in exposing sub-dimensions or member-components that are not part of an intended component;
Unique means of component dealiasing. There must exist one, and only one, such component de-aliasing definition for a component.
There exists one, and only one, definition interface or contract to identify a parent component in a hierarchical relationship of components.
Absence of component crosstalk. There does not exist the necessity to use a member of another component to contribute to the definitive identification of a component.
In such a parent-child relationship, the identifying definition of a parent must not depend on part of the set of member components of a child. A member component of a parent's identity must be the complete child identity without resorting to referencing any or all of the children of a child.
Preempt bi-modal or multi-modal appearances of a data-model.
When there exists two candidate definitions of a component, it is an obvious sign that there exists two different data-models being mixed up as one. That means there is incoherence at the data-model level, or the field level.
A field of applications must use one and only one data-model, coherently.
Detect and identify component mutation. Unless you have performed statistical component analysis of huge data, you probably do not see, or see the need to treat, component mutation.
A data-model may have its some of its components mutate cyclically or gradually.
The mode may be member-rotation or transposition-rotation.
Member-rotation mutation could be distinct swapping of child components between components. Or where completely new components would have to be defined.
Transpositional mutation would manifest as a dimensional-member mutating into an attribute, vice versa.
Each mutation cycle must be identified as a distinct data-modal.
Versionize each mutation. Such that you can pull out a previous version of the data model, when perhaps the need arise to treat an 8 year old mutation of the data model.
In a field or grid of inter-servicing component-applications, there must be one and only one coherent data-model or exists a means for a data-model/version to identify itself.
Are we still asking if we could use Interface Constants? Really ?
There are data-normalization issues at stake more consequential than this mundane question. IF you don't solve those issues, the confusion that you think interface constants cause is comparatively nothing. Zilch.
From the data-model normalization then you determine the components as variables, as properties, as contract interface constants.
Then you determine which goes into value injection, property configuration placeholding, interfaces, final strings, etc.
If you have to use the excuse of needing to locate a component easier to dictate against interface constants, it means you are in the bad habit of not practicing data-model normalization.
Perhaps you wish to compile the data-model into a vcs release. That you can pull out a distinctly identifiable version of a data-model.
Values defined in interfaces are completely assured to be non-mutable. And shareable. Why load a set of final strings into your class from another class when all you need is that set of constants ??
So why not this to publish a data-model contract? I mean if you can manage and normalize it coherently, why not? ...
public interface CustomerService {
public interface Label{
char AssignmentCharacter = ':';
public interface Address{
String Street = "Street";
String Unit= "Unit/Suite";
String Municipal = "City";
String County = "County";
String Provincial = "State";
String PostalCode = "Zip"
}
public interface Person {
public interface NameParts{
String Given = "First/Given name"
String Auxiliary = "Middle initial"
String Family = "Last name"
}
}
}
}
Now I can reference my apps' contracted labels in a way such as
CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family
This confuses the contents of the jar file? As a Java programmer I don't care about the structure of the jar.
This presents complexity to osgi-motivated runtime swapping ? Osgi is an extremely efficient means to allow programmers to continue in their bad habits. There are better alternatives than osgi.
Or why not this? There is no leakage of of the private Constants into published contract. All private constants should be grouped into a private interface named "Constants", because I don't want to have to search for constants and I am too lazy to repeatedly type "private final String".
public class PurchaseRequest {
private interface Constants{
String INTERESTINGName = "Interesting Name";
String OFFICIALLanguage = "Official Language"
int MAXNames = 9;
}
}
Perhaps even this:
public interface PurchaseOrderConstants {
public interface Properties{
default String InterestingName(){
return something();
}
String OFFICIALLanguage = "Official Language"
int MAXNames = 9;
}
}
The only issue with interface constants worth considering is when the interface is implemented.
This is not the "original intention" of interfaces? Like I would care about the "original intention" of the founding fathers in crafting the US Constitution, rather than how the Supreme Court would interpret the written letters of the US Constitution ???
After all, I live in the land of the free, the wild and home of the brave. Be brave, be free, be wild - use the interface. If my fellow-programmers refuse to use efficient and lazy means of programming, am I obliged by the golden rule to lessen my programming efficiency to align with theirs? Perhaps I should, but that is not an ideal situation.