I'm looking at some open source Java projects to get into Java and notice a lot of them have some sort of 'constants' interface.
For instance, processing.org has an interface called PConstants.java, and most other core classes implement this interface. The interface is riddled with static members. Is there a reason for this approach, or is this considered bad practice? Why not use enums where it makes sense, or a static class?
I find it strange to use an interface to allow for some sort of pseudo 'global variables'.
public interface PConstants {
// LOTS OF static fields...
static public final int SHINE = 31;
// emissive (by default kept black)
static public final int ER = 32;
static public final int EG = 33;
static public final int EB = 34;
// has this vertex been lit yet
static public final int BEEN_LIT = 35;
static public final int VERTEX_FIELD_COUNT = 36;
// renderers known to processing.core
static final String P2D = "processing.core.PGraphics2D";
static final String P3D = "processing.core.PGraphics3D";
static final String JAVA2D = "processing.core.PGraphicsJava2D";
static final String OPENGL = "processing.opengl.PGraphicsOpenGL";
static final String PDF = "processing.pdf.PGraphicsPDF";
static final String DXF = "processing.dxf.RawDXF";
// platform IDs for PApplet.platform
static final int OTHER = 0;
static final int WINDOWS = 1;
static final int MACOSX = 2;
static final int LINUX = 3;
static final String[] platformNames = {
"other", "windows", "macosx", "linux"
};
// and on and on
}
It's generally considered bad practice. The problem is that the constants are part of the public "interface" (for want of a better word) of the implementing class. This means that the implementing class is publishing all of these values to external classes even when they are only required internally. The constants proliferate throughout the code. An example is the SwingConstants interface in Swing, which is implemented by dozens of classes that all "re-export" all of its constants (even the ones that they don't use) as their own.
But don't just take my word for it, Josh Bloch also says it's bad:
The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class's exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface.
An enum may be a better approach. Or you could simply put the constants as public static fields in a class that cannot be instantiated. This allows another class to access them without polluting its own API.
Instead of implementing a "constants interface", in Java 1.5+, you can use static imports to import the constants/static methods from another class/interface:
import static com.kittens.kittenpolisher.KittenConstants.*;
This avoids the ugliness of making your classes implement interfaces that have no functionality.
As for the practice of having a class just to store constants, I think it's sometimes necessary. There are certain constants that just don't have a natural place in a class, so it's better to have them in a "neutral" place.
But instead of using an interface, use a final class with a private constructor. (Making it impossible to instantiate or subclass the class, sending a strong message that it doesn't contain non-static functionality/data.)
Eg:
/** Set of constants needed for Kitten Polisher. */
public final class KittenConstants
{
private KittenConstants() {}
public static final String KITTEN_SOUND = "meow";
public static final double KITTEN_CUTENESS_FACTOR = 1;
}
I do not pretend the right to be right, but lets see this small example:
public interface CarConstants {
static final String ENGINE = "mechanical";
static final String WHEEL = "round";
// ...
}
public interface ToyotaCar extends CarConstants //, ICar, ... {
void produce();
}
public interface FordCar extends CarConstants //, ICar, ... {
void produce();
}
// and this is implementation #1
public class CamryCar implements ToyotaCar {
public void produce() {
System.out.println("the engine is " + ENGINE );
System.out.println("the wheel is " + WHEEL);
}
}
// and this is implementation #2
public class MustangCar implements FordCar {
public void produce() {
System.out.println("the engine is " + ENGINE );
System.out.println("the wheel is " + WHEEL);
}
}
ToyotaCar doesnt know anything about FordCar, and FordCar doesnt know about ToyotaCar. principle CarConstants should be changed, but...
Constants should not be changed, because the wheel is round and egine is mechanical, but...
In the future Toyota's research engineers invented electronic engine and flat wheels! Lets see our new interface
public interface InnovativeCarConstants {
static final String ENGINE = "electronic";
static final String WHEEL = "flat";
// ...
}
and now we can change our abstraction:
public interface ToyotaCar extends CarConstants
to
public interface ToyotaCar extends InnovativeCarConstants
And now if we ever need to change the core value if the ENGINE or WHEEL we can change the ToyotaCar Interface on abstraction level, dont touching implementations
Its NOT SAFE, I know,
but I still want to know that do you think about this
There is a lot of hate for this pattern in Java. However, an interface of static constants does sometimes have value. You need to basically fulfill the following conditions:
The concepts are part of the public interface of several
classes.
Their values might change in future releases.
Its critical that all implementations use the same values.
For example, suppose that you are writing an extension to a hypothetical query language. In this extension you are going to expand the language syntax with some new operations, which are supported by an index. E.g. You are going to have a R-Tree supporting geospatial queries.
So you write a public interface with the static constant:
public interface SyntaxExtensions {
// query type
String NEAR_TO_QUERY = "nearTo";
// params for query
String POINT = "coordinate";
String DISTANCE_KM = "distanceInKm";
}
Now later, a new developer thinks he needs to build a better index, so he comes and builds an R* implementation. By implementing this interface in his new tree he guarantees that the different indexes will have identical syntax in the query language. Moreover, if you later decided that "nearTo" was a confusing name, you could change it to "withinDistanceInKm", and know that the new syntax would be respected by all your index implementations.
PS: The inspiration for this example is drawn from the Neo4j spatial code.
Given the advantage of hindsight, we can see that Java is broken in many ways. One major failing of Java is the restriction of interfaces to abstract methods and static final fields. Newer, more sophisticated OO languages like Scala subsume interfaces by traits which can (and typically do) include concrete methods, which may have arity zero (constants!). For an exposition on traits as units of composable behavior, see http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf. For a short description of how traits in Scala compare with interfaces in Java, see http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-5. In the context of teaching OO design, simplistic rules like asserting that interfaces should never include static fields are silly. Many traits naturally include constants and these constants are appropriately part of the public "interface" supported by the trait. In writing Java code, there is no clean, elegant way to represent traits, but using static final fields within interfaces is often part of a good workaround.
According to JVM specification, fields and methods in a Interface can have only Public, Static, Final and Abstract. Ref from Inside Java VM
By default, all the methods in interface is abstract even tough you didn't mention it explicitly.
Interfaces are meant to give only specification. It can not contain any implementations. So To avoid implementing classes to change the specification, it is made final. Since Interface cannot be instantiated, they are made static to access the field using interface name.
I do not have enough reputation to give a comment to Pleerock, therefor do I have to create an answer. I am sorry for that, but he put some good effort in it and I would like to answer him.
Pleerock, you created the perfect example to show why those constants should be independent from interfaces and independent from inheritance. For the client of the application is it not important that there is a technical difference between those implementation of cars. They are the same for the client, just cars. So, the client wants to look at them from that perspective, which is an interface like I_Somecar. Throughout the application will the client use only one perspective and not different ones for each different car brand.
If a client wants to compare cars prior to buying he can have a method like this:
public List<Decision> compareCars(List<I_Somecar> pCars);
An interface is a contract about behaviour and shows different objects from one perspective. The way you design it, will every car brand have its own line of inheritance. Although it is in reality quite correct, because cars can be that different that it can be like comparing completely different type of objects, in the end there is choice between different cars. And that is the perspective of the interface all brands have to share. The choice of constants should not make this impossible. Please, consider the answer of Zarkonnen.
This came from a time before Java 1.5 exists and bring enums to us. Prior to that, there was no good way to define a set of constants or constrained values.
This is still used, most of the time either for backward compatibility or due to the amount of refactoring needed to get rid off, in a lot of project.
Related
I am reading a book about Java and it says that you can declare the whole class as final. I cannot think of anything where I'd use this.
I am just new to programming and I am wondering if programmers actually use this on their programs. If they do, when do they use it so I can understand it better and know when to use it.
If Java is object oriented, and you declare a class final, doesn't it stop the idea of class having the characteristics of objects?
First of all, I recommend this article: Java: When to create a final class
If they do, when do they use it so I can understand it better and know when to use it.
A final class is simply a class that can't be extended.
(It does not mean that all references to objects of the class would act as if they were declared as final.)
When it's useful to declare a class as final is covered in the answers of this question:
Good reasons to prohibit inheritance in Java?
If Java is object oriented, and you declare a class final, doesn't it stop the idea of class having the characteristics of objects?
In some sense yes.
By marking a class as final you disable a powerful and flexible feature of the language for that part of the code. Some classes however, should not (and in certain cases can not) be designed to take subclassing into account in a good way. In these cases it makes sense to mark the class as final, even though it limits OOP. (Remember however that a final class can still extend another non-final class.)
In Java, items with the final modifier cannot be changed!
This includes final classes, final variables, and final methods:
A final class cannot be extended by any other class
A final variable cannot be reassigned another value
A final method cannot be overridden
One scenario where final is important, when you want to prevent inheritance of a class, for security reasons. This allows you to make sure that code you are running cannot be overridden by someone.
Another scenario is for optimization: I seem to remember that the Java compiler inlines some function calls from final classes. So, if you call a.x() and a is declared final, we know at compile-time what the code will be and can inline into the calling function. I have no idea whether this is actually done, but with final it is a possibility.
The best example is
public final class String
which is an immutable class and cannot be extended.
Of course, there is more than just making the class final to be immutable.
If you imagine the class hierarchy as a tree (as it is in Java), abstract classes can only be branches and final classes are those that can only be leafs. Classes that fall into neither of those categories can be both branches and leafs.
There's no violation of OO principles here, final is simply providing a nice symmetry.
In practice you want to use final if you want your objects to be immutable or if you're writing an API, to signal to the users of the API that the class is just not intended for extension.
Relevant reading: The Open-Closed Principle by Bob Martin.
Key quote:
Software Entities (Classes, Modules,
Functions, etc.) should be open for
Extension, but closed for
Modification.
The final keyword is the means to enforce this in Java, whether it's used on methods or on classes.
The keyword final itself means something is final and is not supposed to be modified in any way. If a class if marked final then it can not be extended or sub-classed. But the question is why do we mark a class final? IMO there are various reasons:
Standardization: Some classes perform standard functions and they are not meant to be modified e.g. classes performing various functions related to string manipulations or mathematical functions etc.
Security reasons: Sometimes we write classes which perform various authentication and password related functions and we do not want them to be altered by anyone else.
I have heard that marking class final improves efficiency but frankly I could not find this argument to carry much weight.
If Java is object oriented, and you declare a class final, doesn't it
stop the idea of class having the characteristics of objects?
Perhaps yes, but sometimes that is the intended purpose. Sometimes we do that to achieve bigger benefits of security etc. by sacrificing the ability of this class to be extended. But a final class can still extend one class if it needs to.
On a side note we should prefer composition over inheritance and final keyword actually helps in enforcing this principle.
final class can avoid breaking the public API when you add new methods
Suppose that on version 1 of your Base class you do:
public class Base {}
and a client does:
class Derived extends Base {
public int method() { return 1; }
}
Then if in version 2 you want to add a method method to Base:
class Base {
public String method() { return null; }
}
it would break the client code.
If we had used final class Base instead, the client wouldn't have been able to inherit, and the method addition wouldn't break the API.
A final class is a class that can't be extended. Also methods could be declared as final to indicate that cannot be overridden by subclasses.
Preventing the class from being subclassed could be particularly useful if you write APIs or libraries and want to avoid being extended to alter base behaviour.
In java final keyword uses for below occasions.
Final Variables
Final Methods
Final Classes
In java final variables can't reassign, final classes can't extends and final methods can't override.
Be careful when you make a class "final". Because if you want to write an unit test for a final class, you cannot subclass this final class in order to use the dependency-breaking technique "Subclass and Override Method" described in Michael C. Feathers' book "Working Effectively with Legacy Code". In this book, Feathers said, "Seriously, it is easy to believe that sealed and final are a wrong-headed mistake, that they should never have been added to programming languages. But the real fault lies with us. When we depend directly on libraries that are out of our control, we are just asking for trouble."
If the class is marked final, it means that the class' structure can't be modified by anything external. Where this is the most visible is when you're doing traditional polymorphic inheritance, basically class B extends A just won't work. It's basically a way to protect some parts of your code (to extent).
To clarify, marking class final doesn't mark its fields as final and as such doesn't protect the object properties but the actual class structure instead.
TO ADDRESS THE FINAL CLASS PROBLEM:
There are two ways to make a class final. The first is to use the keyword final in the class declaration:
public final class SomeClass {
// . . . Class contents
}
The second way to make a class final is to declare all of its constructors as private:
public class SomeClass {
public final static SOME_INSTANCE = new SomeClass(5);
private SomeClass(final int value) {
}
Marking it final saves you the trouble if finding out that it is actual a final, to demonstrate look at this Test class. looks public at first glance.
public class Test{
private Test(Class beanClass, Class stopClass, int flags)
throws Exception{
// . . . snip . . .
}
}
Unfortunately, since the only constructor of the class is private, it is impossible to extend this class. In the case of the Test class, there is no reason that the class should be final. The Test class is a good example of how implicit final classes can cause problems.
So you should mark it final when you implicitly make a class final by making it's constructor private.
One advantage of keeping a class as final :-
String class is kept final so that no one can override its methods and change the functionality. e.g no one can change functionality of length() method. It will always return length of a string.
Developer of this class wanted no one to change functionality of this class, so he kept it as final.
The other answers have focused on what final class tells the compiler: do not allow another class to declare it extends this class, and why that is desirable.
But the compiler is not the only reader of the phrase final class. Every programmer who reads the source code also reads that. It can aid rapid program comprehension.
In general, if a programmer sees Thing thing = that.someMethod(...); and the programmer wants to understand the subsequent behaviour of the object accessed through the thing object-reference, the programmer must consider the Thing class hierarchy: potentially many types, scattered over many packages. But if the programmer knows, or reads, final class Thing, they instantly know that they do not need to search for and study so many Java files, because there are no derived classes: they need study only Thing.java and, perhaps, it's base classes.
Yes, sometimes you may want this though, either for security or speed reasons. It's done also in C++. It may not be that applicable for programs, but moreso for frameworks.
http://www.glenmccl.com/perfj_025.htm
think of FINAL as the "End of the line" - that guy cannot produce offspring anymore. So when you see it this way, there are ton of real world scenarios that you will come across that requires you to flag an 'end of line' marker to the class. It is Domain Driven Design - if your domain demands that a given ENTITY (class) cannot create sub-classes, then mark it as FINAL.
I should note that there is nothing stopping you from inheriting a "should be tagged as final" class. But that is generally classified as "abuse of inheritance", and done because most often you would like to inherit some function from the base class in your class.
The best approach is to look at the domain and let it dictate your design decisions.
As above told, if you want no one can change the functionality of the method then you can declare it as final.
Example: Application server file path for download/upload, splitting string based on offset, such methods you can declare it Final so that these method functions will not be altered. And if you want such final methods in a separate class, then define that class as Final class. So Final class will have all final methods, where as Final method can be declared and defined in non-final class.
Let's say you have an Employee class that has a method greet. When the greet method is called it simply prints Hello everyone!. So that is the expected behavior of greet method
public class Employee {
void greet() {
System.out.println("Hello everyone!");
}
}
Now, let GrumpyEmployee subclass Employee and override greet method as shown below.
public class GrumpyEmployee extends Employee {
#Override
void greet() {
System.out.println("Get lost!");
}
}
Now in the below code have a look at the sayHello method. It takes Employee instance as a parameter and calls the greet method hoping that it would say Hello everyone! But what we get is Get lost!. This change in behavior is because of Employee grumpyEmployee = new GrumpyEmployee();
public class TestFinal {
static Employee grumpyEmployee = new GrumpyEmployee();
public static void main(String[] args) {
TestFinal testFinal = new TestFinal();
testFinal.sayHello(grumpyEmployee);
}
private void sayHello(Employee employee) {
employee.greet(); //Here you would expect a warm greeting, but what you get is "Get lost!"
}
}
This situation can be avoided if the Employee class was made final. Just imagine the amount of chaos a cheeky programmer could cause if String Class was not declared as final.
Final class cannot be extended further. If we do not need to make a class inheritable in java,we can use this approach.
If we just need to make particular methods in a class not to be overridden, we just can put final keyword in front of them. There the class is still inheritable.
Final classes cannot be extended. So if you want a class to behave a certain way and don't someone to override the methods (with possibly less efficient and more malicious code), you can declare the whole class as final or specific methods which you don't want to be changed.
Since declaring a class does not prevent a class from being instantiated, it does not mean it will stop the class from having the characteristics of an object. It's just that you will have to stick to the methods just the way they are declared in the class.
Android Looper class is a good practical example of this.
http://developer.android.com/reference/android/os/Looper.html
The Looper class provides certain functionality which is NOT intended to be overridden by any other class. Hence, no sub-class here.
I know only one actual use case: generated classes
Among the use cases of generated classes, I know one: dependency inject e.g. https://github.com/google/dagger
Object Orientation is not about inheritance, it is about encapsulation. And inheritance breaks encapsulation.
Declaring a class final makes perfect sense in a lot of cases. Any object representing a “value” like a color or an amount of money could be final. They stand on their own.
If you are writing libraries, make your classes final unless you explicitly indent them to be derived. Otherwise, people may derive your classes and override methods, breaking your assumptions / invariants. This may have security implications as well.
Joshua Bloch in “Effective Java” recommends designing explicitly for inheritance or prohibiting it and he notes that designing for inheritance is not that easy.
Consider following interface.
public interface ThirdPartyApiHandler {
public OperationResult doOperation(OperationInput input);
public static class OperationResult {
//members of OpeationResult. metrics after file processing
private int successfulRecords;
private int failedRecords;
}
public static class OperationInput {
//implementations call third party API to process this file.
private String inputBatchFile;
}
//Constant which would be same across all implementations.
public static final int GLOBAL_CONSTANT = 1;
}
Is above interface a bad design?
OperationResult and OperationInput are defined as static class. They would be only used by implementations and not anywhere else. Advantage that I see here is - I don't have to create separate files for these two classes. Also they get namespace of parent class.
I have read about constant interface. But in this case, I am defining constant in normal interface which are bound to be same across all implementations and would be used in those implementations.
I am using this pattern for first time so wanted to get suggestions.
OperationResult and OperationInput are defined as static inner class.
They won't be used anywhere else.
That's OK since they will not be used anywhere else. If they're long than I would prefer to have them in separate classes.
I have read about constant interface. But in this case, I am defining constant in normal interface which are bound to be same across all implementations and would be used in those implementations.
That's a good place to declare such a field.
Having nested classes in interfaces is only matter of additional namespace. This approach help to organize the code when small interfaces are created to support simple data structure.
I recommend you this lecture: Java Tip 75: Use nested classes for better organization.
Note that public and static are redundant in this case so you do not need them. What you need to remember is that having such classes do not limit other developers to use them in other parts of code.
From my point of view, this is a good design but, i would extend and replace the class with interfaces.
public interface ThirdPartyApiHandler {
OperationResult doOperation(OperationInput input);
interface OperationResult {
int getSuccessfulRecords();
int getFailedRecords();
}
interface OperationInput {
String getInputBatchFile();
}
final int GLOBAL_CONSTANT = 1; //This could be replaced by enum but no need
}
Is above interface a bad design?
That would depend on your implementation design and it's usability in your project. Logic looks all legal to me. Possible use case of such a design can be as follows
public interface A {
static class B {
public static boolean verifyState( A a ) {
return (true if object implementing class A looks to be in a valid state)
}
}
}
Also
public static class OperationResult {
//members of OpeationResult. metrics after file processing
private int successfulRecords;
private int failedRecords;
}
In above class you have instance variables successfulRecords and failedRecords . why not make the instance variable of these static classes also static so that you can access them using ThirdPartyApiHandler.OperationResult.successfulRecords. You can even have static getters and setters for your variables.
OperationResult and OperationInput are defined as static inner class.
Contrarily to popular belief there's no such thing as an "static inner class": this simply makes no sense, there's nothing "inner" and no "outter" class when a nested class is static, so it cannot be "static inner".
Picked up above from this SO question. Read the 1st answer. I think that will answer all your questions.
Is above interface a bad design?
Quite simply, yes.
Putting any logic in an interface is semantically incorrect. An interface exposes functionality to consumers - that is its single purpose, and that should not be diluted.
Consider implementing any common functionality in a base implementation class and use inheritance, or in one or more services and use composition, in your different interface implementations.
EDIT - quote from Joshua Bloch's Effective Java
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.
Why we use public static final declaration of instance variables in a Java Interface?
All the variables are implicitly public static final in a Java Interface.
Is it a good coding practice to use public static final in constant variable although it is declared inside an Interface.
For example :
public interface TestInterface{
public static final String EX_CONSTANT = "ABC";
public static final int EX_INT_CONSTANT = 5;
public static final double EX_DOUBLE = 5.0;
public static final Integer EX_INTEGER = 10;
}
Use of uniform syntax in both classes and interfaces simplifies refactoring.
You may want to turn your interface into a class somewhere in future, or move these fields into a class, and you'll get a semantical difference if you overlook some fields defined without public static final (of course, we have tools for refactoring, but nonetheless).
I think it's the same thing as support of #Overriden annotation for implementations of methods declared in interfaces that was introduced in Java 6 - it's redundant in its current form, but may become useful in case of refactoring.
I don't think so. All interface variables are implicitly public static final so no meaning to mark them same.
From the book Effective java by JOshua Bloch
Item 19: 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. Here is an example:
// Constant interface antipattern - do not use!
public interface PhysicalConstants {
// Avogadro's number (1/mol)
static final double AVOGADROS_NUMBER = 6.02214199e23;
// Boltzmann constant (J/K)
static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
// Mass of the electron (kg)
static final double ELECTRON_MASS = 9.10938188e-31;
}
The constant interface pattern is a poor use of interfaces. That a class uses
some constants internally is an implementation detail. Implementing a constant
interface causes this implementation detail to leak into the class’s exported API. It
is of no consequence to the users of a class that the class implements a constant
interface. In fact, it may even confuse them. Worse, it represents a commitment: if
in a future release the class is modified so that it no longer needs to use the constants,
it still must implement the interface to ensure binary compatibility. If a
nonfinal class implements a constant interface, all of its subclasses will have their
namespaces polluted by the constants in the interface.
There are several constant interfaces in the Java platform libraries, such as
java.io.ObjectStreamConstants. These interfaces should be regarded as
anomalies and should not be emulated.
If you want to export constants, there are several reasonable choices. 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 (Item 30). Otherwise, you should export the constants
with a noninstantiable utility class (Item 4). Here is a utility class version of the
PhysicalConstants example above:
// 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;
}
Normally a utility class requires clients to qualify constant names with a class
name, for example, PhysicalConstants.AVOGADROS_NUMBER. If you make heavy
use of the constants exported by a utility class, you can avoid the need for qualifying
the constants with the class name by making use of the static import facility,
introduced in release 1.5:
// Use of static import to avoid qualifying constants
import static com.effectivejava.science.PhysicalConstants.*;
public class Test {
double atoms(double mols) {
return AVOGADROS_NUMBER * mols;
}
...
// Many more uses of PhysicalConstants justify static import
}
In summary, interfaces should be used only to define types. They should not
be used to export constants.
IMO, Interface is a contract. Once variables are declared or defined they are not going to change. That's why generally we make them public static final.
Readability is another factor which makes declaration redundant.
Admittedly, it's redundant. Usually people just don't know that they're implicitly public static final and declare it anyway. Ditto with things like declaring:
public abstract interface Test { // Interfaces are always abstract
public void testMethod(); // Interface methods are always public
abstract void anotherTestMethod(); // Also redundant
}
Usually it just boils down to the fact that people don't know that they don't have to declare it one way or the other. I once talked to someone (who was a seasoned programmer) that thought the default case in switch is required or it won't compile.
That being said, the only argument to be made for adding them is that they clarify what their actual visibility and whatnot actually is. It's a matter of readability and clarification, and whether or note to include them is irrelevant in terms of how it actually behaves.
When you are working in a team of programmers, you will find junior programmers who do not know the fact that by default the variables are public static final in the interface, and seeing the variables declared that way will give them extra information about the interface and the use of its variables.
You are correct: it is redundant. I don't like to add redundant syntax at any time. However the practice does has its adherents. Some also like to add parentheses around return-expressions, on the fallacious grounds that it's like an 'if' statement; extra parentheses to 'clarify' arithmetic expressions that a third-grader would understand; etc. It's all part of the rich tapestry of life.
Today I looked at the ZipEntry class and found the following:
public class ZipEntry implements ZipConstants, Cloneable
ZipConstants does not define any methods - only constants (static final int LOCHDR = 30)
It then occurred to me that implementing the interface with constants lets you access those constants directly, as if they were defined in the class itself. For example:
public interface Constants {
static final int CONST = 2;
}
public class implements Constants {
int doSomething(int input) {
return CONST * input;
}
}
Is there another reason not to use this, apart from:
it is at first confusing where the constant is coming from
it is considered wrong to use interfaces for constants definition
I'm curious because it is definitely not a very common practice.
Another reasons not to use this:
Since Java 5, there is a "clean" language feature that achieves the same goal: static imports.
Implementing interfaces to use constants is basically a pre-Java-5 hack to simulate static imports.
It is not so rare as you might think, for instance in the static analysis of Parasofts JTest both the rule that constants should be declared in a class and the rule that constants should be declared in interfaces are present, and it's up to the project to choose between them.
That said, in all my projects I disallow the practice of defining constants in interfaces. Creating a meaningfull class and being explicit about the context of a constant makes code much more readable and thus maintainable than in the case where a developer has to check that constants used in one class are actually the same as those in another class (or not.)
I think that using an interface for shared constants is an example of confusing two different concepts:
Code reuse
Subtyping
In my experience using subclassing, or interface implementation simply to prevent the duplication of code leads to problems. Your code becomes more fragile. For example, someone might accidental redefine the constant - especially if your class hierarchy is several classes deep.
It is often better to use composition to keep your code DRY.
Another problem with using inheritance in this way is that generally this type of inheritance forms part of the API of your class. The hierarchy of the class is visible outside of the class. This breaks encapsulation. There is no need for you to expose your use of the constants outside of the class, they are to do with how you have chosen to implement your class and are not part of its API (in your example).
This can lead to horrible backwards compatibility problems. Someone else might come along and write code like this:
public interface Constants {
static final int CONST = 2;
}
public class MyClass implements Constants {
int doSomething(int input) {
return CONST * input;
}
}
public class ThirdPartyClass {
int doSomethingElse(int input) {
return MyClass.CONST + input;
}
}
Now, if you decide you no longer need to use CONST in MyClass you are stuck. Because ThirdPartyClass has create a dependency on CONST being available in MyClass.
You can end up with this. Where MyClass is not using any of the constants in the interface, but still has to implement it.
public interface Constants {
static final int CONST = 2;
}
public class MyClass implements Constants {
int doSomething(int input) {
return input;
}
}
public class ThirdPartyClass {
int doSomethingElse(int input) {
return MyClass.CONST + input;
}
}
In short; never do this!
... because it is considered wrong to use interfaces for constants definition
This is a bad reason not to do something. In fact, it is not a reason at all.
EDIT
Consider this.
The reason that XXX is bad style is YYY.
The reason you should do XXX is that it is bad style.
How many substantive reasons are there for not doing XXX? One or two?
If the answer is two, I can make it three, four, five and so on by adding extra tenuous chains of reasons. For example "The reason you should not do XXX is because it is a bad idea." "The reasons it is a bad idea is that it is bad style". And so on. That is plainly silly.
No the real reason for not doing XXX is YYY, and the "Bad style" reason is not a substantive reason. Rather, it is a short cut for saying don't do XXX because of YYY and ZZZ, and any other substantive reasons.
In fact, even the OP's "it is confusing" reason is incompletely stated. WHY is it confusing?
Because an interface is normally a type with classes that implement the interface are subtype. But a constant only interface is not a type in any useful sense, and classes that implement the interface are not subtypes in any useful sense. Ultimately, this is the real reason that implementing constant-only interfaces is called bad style and an "anti-pattern", and it is the main reason that the static imports were added in Java 5.
Nope, this is also known as the "Constant Interface Antipattern". An alternative is writing a concrete class which defines the constants and then use static import.
Class Constants
package util;
public class Constants {
public static final String CONSTANT_STRING = "abc";
private Constants() {
throw new AssertionError();
}
}
Class Test
import static util.Constants.CONSTANT_STRING;
public class Test {
System.out.println(CONSTANT_STRING);
}
See
Wikipedia
for further details.
One of the reasons for not putting your constants in your interface is is that if you expose your interface to a thirdparty they have access to your constants.
This may not seem like a bad idea to start off but imagine if you want to change the value of a constant but people are still using an old interface.
When you add something to an interface it has the potential to be set in stone so only add what you want others to see and use.
This question already has answers here:
Java 8: Interface with static methods instead of static util class
(5 answers)
Closed 7 years ago.
For the past decade or so, I've been using the pattern below for my Java utility classes. The class contains only static methods and fields, is declared final so it can't be extended, and has a private constructor so it can't be instantiated.
public final class SomeUtilityClass {
public static final String SOME_CONSTANT = "Some constant";
private SomeUtilityClass() {}
public static Object someUtilityMethod(Object someParameter) {
/* ... */
return null;
}
}
Now, with the introduction of static methods in interfaces in Java 8, I lately find myself using a utility interface pattern:
public interface SomeUtilityInterface {
String SOME_CONSTANT = "Some constant";
static Object someUtilityMethod(Object someParameter) {
/* ... */
return null;
}
}
This allows me to get rid of the constructor, and a lot of keywords (public, static, final) that are implicit in interfaces.
Are there any downsides to this approach? Are there any benefits to using a utility class over a utility interface?
You should use interface only if you expect that somebody would implement it. For example, java.util.stream.Stream interface has a bunch of static methods which could be located in some Streams or StreamUtils class prior to Java 8. However it's a valid interface which has non-static methods as well and can be implemented. The java.util.Comparable is another example: all static methods there just support the interface. You cannot forbid users from implementing your public interface, but for utility class you can forbid them to instantiate it. Thus for the code clarity I suggest not to use interfaces unless they are intended to be implemented.
A note regarding #saka1029 answer. While it's true that you cannot define helper private methods and constants in the same interface, it's not a problem to create a package-private class in the same package like MyInterfaceHelper which will have all the necessary implementation-related stuff. In general package-private classes are good to hide your implementation details from the outer world.
Going based on the person who coined the Constant Interface pattern an anti-pattern, I would say although you don't intend the client(s) to implement the interface, it's still possible, possibly easier, and shouldn't be allowed:
APIs should be easy to use and hard to misuse. It should be easy to do simple things; possible to do complex things; and impossible, or at least difficult, to do wrong things.
Although as mentioned below, it really depends on the target audience
A lot of easy-to-use designs patterns get a lot of criticism (Context pattern, Singleton pattern, Constant Interface pattern). Heck, even design principles such as the law of demeter gets criticised for being too verbose.
I'd hate to say it, but these kinds of decisions are opinion based. Although the context pattern is seen as an anti-pattern, it's apparent in mainstream frameworks such as Spring and the Android SDK. It boils down to the environment, as well as target audience.
The main downside that I can find is listed as the third listing under "downsides" in the Constant Interface wiki:
If binary code compatibility is required in future releases, the constants interface must remain forever an interface (it cannot be converted into a class), even though it has not been used as an interface in the conventional sense.
If you ever figure "Hey, this actually isn't a contract and I want to enforce stronger design", you will not be able to change it. But as I've said, it's up to you; maybe you won't care to change it in the future.
On top of that, code clarity as mentioned by #TagirValeev. Interfaces have the intent of being implemented; if you don't want someone to implement the API you're supplying, don't make it implementable. But I believe this revolves around the "target audience" statement. Not gonna lie, I'm with you on the less-verbose foundation, but it depends on who my code is for; wouldn't wanna use a constant interface for code that may get reviewed.
You should not use interface.
Interfaces cannot have private constants and static initializers.
public class Utility {
private Utility() {}
public static final Map<String, Integer> MAP_CONSTANT;
static {
Map<String, Integer> map = new HashMap<>();
map.put("zero", 0);
map.put("one", 1);
map.put("three", 3);
MAP_CONSTANT = Collections.unmodifiableMap(map);
}
private static String PRIVATE_CONSTANT = "Hello, ";
public static String hello(String name) {
return PRIVATE_CONSTANT + name;
}
}
I think it would work. I think the variable SOME_CONSTANT defaults to being static final in your SomeUtilityInterface, even though you didn't explicitly say so. So, it would work as a Utility but wouldn't you have some mutability problems that you wouldn't have with a regular class with all member variables being required to be final? As long as thats not an issue with your particular implementation of the default methods, I can't think of a problem.