Java Interface - constants and static class in normal interface - java

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.

Related

Why `private static` field is not allowed in Java 8 interface?

When I'm trying to compile the following code
public interface SomeInterface{
private static Logger logger = Logger.getLogger();
public default void someMethod(){
logger.info("someMethod: default implementation");
}
}
I get an error
Illegal modifier for the interface field SomeInterface.logger; only public, static & final are permitted
When I delete private modifier, code compiles, but I don't want other classes from the package to see this field.
Why Java doesn't allow me to do such thing when it actually does make sense?
In the pre-Java-8 view of the world, interfaces were purely for interface contracts, and private members exist purely for implementation, so this restriction was completely sensible.
In the post-Java-8 world, where interfaces can carry behavior (but not state), it starts to be reasonable to ask whether other features of classes should be applied to interfaces as well. (However, just because something might be "reasonable" doesn't mean it must be supported; there is often more than one reasonable way to construct the world.)
In Java 9, private methods in interfaces will be supported.
Interfaces are not classes. They have no private state. Even a public logger in the interface is a design smell and an abuse of interfaces.
The use case for static fields in interfaces is mainly for compile-time constants, not for stateful objects.
The goal of interface is to define something implemented by other classes. A private field does not define anything as it is not visible outside the interface. Hence it does not make any sense in this construct. It may be some hacks how to use it (maybe from interface inner classes) but would not look like a good design anyway.
If you actually implement part of the functionality, use abstract class instead.
Interface is like a blueprint of any class, where you declare your members. Any class that implement that interface is responsible for its definition.
Private members can only be accessed by same class member, which does not make sense in terms of interface.
Protected members can be accessed by same class member and inherited class members, but in case of interface we never extend an interface, we implement it. So any interface can only contain public methods generally,
public interface SomeInterface {
public default void someMethod() {
SomeInterfaceInternal.logger.info("someMethod: default implementation");
}
}
final class SomeInterfaceInternal {
protected static final Logger logger = LoggerFactory.getLogger(SomeInterface.class);
}

Public static final declaration of an instance variables in JAVA Interfaces

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.

why interface cannot be final?

JLS 2.13.1 Interface Modifiers
An interface cannot be final, because the implementation of such a class could never be completed.
If I can write create static inner classes in interface I can provide implementation in it so why is such restriction
interface Type {
// Normal
class Value {
private Value() {
}
public void print() {
System.out.println("Test");
}
}
public final Value value = new Value();
}
Well in Interfaces you cannot provide any form of implementation at all: Not even static methods. It doesn't make sense to make any method final because they're yet to be implemented.
Code Examples:
If let say I have an interface named IExample and its concrete implementation Example:
interface IExample{
public final void run();
}
class Example implements IExample{
// wait! I can't override because it's final! but it's yet to be implemented?!
public void run(){
}
}
BTW: nested classes were not available when this restriction was first defined, so really the question might be why this restriction was not lifted.
A final class cannot have any sub-classes. It is considered best practice to only use interfaces for defining method(s) of sub-classes, so the two are contradictory.
You can use interfaces for other things
annotations
javadocs
constants
defining nested classes only.
but these are incidental to the purpose of an interface.
"When the final keyword appears in a class declaration, it means that the class may never be subclassed or overridden. This prevents over-specialization of a particular class. In some sense, the person who created the class considered any further changes to be tangential to its primary purpose."
Reference: Final
Interface represent behaviour, rather than implementation, therefore it makes no sense for it to be final.
If I can write create static inner classes in interface I can provide implementation in it so why is such restriction
Yes, you can declare an inner class there, but point remains that a final interface would be an interface that it is impossible to implement. Any class that implemented it would be violating the final restriction. The Java designers concluded that this didn't make much sense, and since there are no convincing use-cases for final interfaces with nested classes*, there is no justification for relaxing this restriction.
* - I won't claim that one could not invent a use-case. However, I've never heard of people writing interfaces with inner classes, with the intention was that the interface should not be implemented.

Header like Class for defining constants in Java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you define a class of constants in Java?
I would like to define a class in my package to contain only the constant vales like defines in C. I am a C programmer learning Java so perhaps that is why I still want to have some header like class :)
For this purpose here is the class I have:
package com.myclasses
public class defines{
public static byte final ID_1= 0x01;
public static final ID_2= 0x02;
public static String company_name="XYZ";
}
Then somewhere in a another class in the same package, I use these defines as follows:
byte idval = defines.ID_1;
... and so on.
My question is for such a "header" class what is the best way of defining it?
It has only static variables so should I define the class also static?
What about the access modifier? Since it has defines in it I thought it could be made "public".
Please advise.
Don't
There are hardly any constants that have value in their own. They only make sense in context. That context is a real class, i.e. a class that has instances (at least one). Declare the constants in that class.
As for the modifiers: reduce the scope as far as possible: Private if only used inside the class where they are declared, public if anybody using the class needs the constants as well.
If you declare more then one constant of same type in one class, think about if a enum makes mores sense.
And yes, constants should be static.
This pattern is called the "constant class" pattern (I think).
One way of using it is to make it an interface and implement it, then you get the references for "free":
public interface Defines {
static byte final ID_1= 0x01;
static final ID_2= 0x02;
// etc
}
public class MyClass implements Defines {
byte idval = ID_1; // Note: No need to refer to the class "Defines" here
}
but most people consider this an anti-pattern, because it isn't a real interface (it has no methods). Nevertheless, it is kind of cool, and may be a good way for you to ease into java.
The "standard" approach is to define a "utility class", which is one that has only static fields and methods, give it a private constructor to reinforce that you shouldn't create one of these. This is what you have done - keep doing it.
If you have a few constants that are different values of "the same thing", eg directions on a compass, etc, strongly consider using an enum. You should read up on them.
Use a final class
eg : public final class defines {
// private constructor
private defines() {
}
}
The constants should be defined as
public static final <type> constantName = <value>;
Wouldn't recommend enums in this scenario as Enums should be used when we are having constants which are having some relation between them.
Having a utility class like this, is the approach we use in our project to define constants that needs to be accessed across a project.
If you needs the constants only in that certain class then defining them in the class itself will be the best solution. eg:
private static final <type> constantName = <value>;
Just use an Interface in Java to define all your Constants..
public interface Const {
String GOVERNMENT = "Government";
String PUBLIC = "Public";
...
}
You can use class also.

Should a class implement a constants-only interface?

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.

Categories