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);
}
Related
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.
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.
I have a quite simple question:
I want to have a Java Class, which provides one public static method, which does something. This is just for encapsulating purposes (to have everything important within one separate class)...
This class should neither be instantiated, nor being extended. That made me write:
final abstract class MyClass {
static void myMethod() {
...
}
... // More private methods and fields...
}
(though I knew, it is forbidden).
I also know, that I can make this class solely final and override the standard constructor while making it private.
But this seems to me more like a "Workaround" and SHOULD more likely be done by final abstract class...
And I hate workarounds. So just for my own interest: Is there another, better way?
You can't get much simpler than using an enum with no instances.
public enum MyLib {;
public static void myHelperMethod() { }
}
This class is final, with explicitly no instances and a private constructor.
This is detected by the compiler rather than as a runtime error. (unlike throwing an exception)
Reference: Effective Java 2nd Edition Item 4 "Enforce noninstantiability with a private constructor"
public final class MyClass { //final not required but clearly states intention
//private default constructor ==> can't be instantiated
//side effect: class is final because it can't be subclassed:
//super() can't be called from subclasses
private MyClass() {
throw new AssertionError()
}
//...
public static void doSomething() {}
}
No, what you should do is create a private empty constructor that throws an exception in it's body. Java is an Object-Oriented language and a class that is never to be instantiated is itself a work-around! :)
final class MyLib{
private MyLib(){
throw new IllegalStateException( "Do not instantiate this class." );
}
// static methods go here
}
No, abstract classes are meant to be extended. Use private constructor, it is not a workaround - it is the way to do it!
Declare the constructor of the class to be private. That ensure noninstantiability and prevents subclassing.
The suggestions of assylias (all Java versions) and Peter Lawrey (>= Java5) are the standard way to go in this case.
However I'd like to bring to your attention that preventing a extension of a static utility class is a very final decision that may come to haunt you later, when you find that you have related functionality in a different project and you'd in fact want to extend it.
I suggest the following:
public abstract MyClass {
protected MyClass() {
}
abstract void noInstancesPlease();
void myMethod() {
...
}
... // More private methods and fields...
}
This goes against established practice since it allows extension of the class when needed, it still prevents accidental instantiation (you can't even create an anonymous subclass instance without getting a very clear compiler error).
It always pisses me that the JDK's utility classes (eg. java.util.Arrays) were in fact made final. If you want to have you own Arrays class with methods for lets say comparison, you can't, you have to make a separate class. This will distribute functionality that (IMO) belongs together and should be available through one class. That leaves you either with wildly distributed utility methods, or you'd have to duplicate every one of the methods to your own class.
I recommend to never make such utility classes final. The advantages do not outweight the disadvantages in my opinion.
You can't mark a class as both abstract and final. They have nearly opposite
meanings. An abstract class must be subclassed, whereas a final class must not be
subclassed. If you see this combination of abstract and final modifiers, used for a class or method declaration, the code will not compile.
This is very simple explanation in plain English.An abstract class cannot be instantiated and can only be extended.A final class cannot be extended.Now if you create an abstract class as a final class, how do you think you're gonna ever use that class, and what is,in reality, the rationale to put yourself in such a trap in the first place?
Check this Reference Site..
Not possible. An abstract class without being inherited is of no use and hence will result in compile time error.
Thanks..
I am just trying to understand why all fields defined in an Interface are implicitly static and final. The idea of keeping fields static makes sense to me as you can't have objects of an interface but why they are final (implicitly)?
Any one knows why Java designers went with making the fields in an interface static and final?
An interface is intended to specify an interaction contract, not implementation details. A developer should be able to use an implementation just by looking at the interface, and not have to look inside the class which implements it.
An interface does not allow you to create an instance of it, because you cannot specify constructors. So it cannot have instance state, although interface fields can define constants, which are implicitly static and final.
You cannot specify method bodies or initializer blocks in an interface, although since Java 8 you can specify default methods with bodies. This feature is intended to allow new methods to be added to existing interfaces without having to update all the implementations. But you still cannot execute such a method, without first creating an instance implementing the interface.
Aside: Note that you can implement an interface with an anonymous inner class:
interface Foo {
String bar();
}
class FooBar {
Foo anonymous = new Foo() {
public String bar() {
return "The Laundromat Café";
};
}
You have to provide the full implementation of the interface for the anonymous inner class to compile.
new Foo() is initializing the anonymous inner class with its default constructor.
Reason for being final
Any implementations can change value of fields if they are not defined as final. Then they would become a part of the implementation. An interface is a pure specification without any implementation.
Reason for being static
If they are static, then they belong to the interface, and not the object, nor the run-time type of the object.
There are a couple of points glossed over here:
Just because fields in an interface are implicitly static final does not mean they must be compile-time constants, or even immutable. You can define e.g.
interface I {
String TOKEN = SomeOtherClass.heavyComputation();
JButton BAD_IDEA = new JButton("hello");
}
(Beware that doing this inside an annotation definition can confuse javac, relating to the fact that the above actually compiles to a static initializer.)
Also, the reason for this restriction is more stylistic than technical, and a lot of people would like to see it be relaxed.
The fields must be static because they can't be abstract (like methods can). Because they can't be abstract, the implementers will not be able to logically provide the different implementation of the fields.
The fields must be final, I think, because the fields may be accessed by many different implementers allows they to be changeable might be problematic (as synchronization). Also to avoid it to be re-implemented (hidden).
Just my thought.
I consider the requirement that the fields be final as unduly restrictive and a mistake by the Java language designers. There are times, e.g. tree handling, when you need to set constants in the implementation which are required to perform operations on an object of the interface type. Selecting a code path on the implementing class is a kludge. The workaround which I use is to define an interface function and implement it by returning a literal:
public interface iMine {
String __ImplementationConstant();
...
}
public class AClass implements iMine {
public String __ImplementationConstant(){
return "AClass value for the Implementation Constant";
}
...
}
public class BClass implements iMine {
public String __ImplementationConstant(){
return "BClass value for the Implementation Constant";
}
...
}
However, it would be simpler, clearer and less prone to aberrant implementation to use this syntax:
public interface iMine {
String __ImplementationConstant;
...
}
public class AClass implements iMine {
public static String __ImplementationConstant =
"AClass value for the Implementation Constant";
...
}
public class BClass implements iMine {
public static String __ImplementationConstant =
"BClass value for the Implementation Constant";
...
}
Specification, contracts... The machine instruction for field access uses object address plus field offset. Since classes can implement many interfaces, there is no way to make non-final interface field to have the same offset in all classes that extend this interface. Therefore different mechanism for field access must be implemented: two memory accesses (get field offset, get field value) instead of one plus maintaining kind of virtual field table (analog of virtual method table). Guess they just didn't want to complicate jvm for functionality that can be easily simulated via existing stuff (methods).
In scala we can have fields in interfaces, though internally they are implemented as I explained above (as methods).
static:
Anything (variable or method) that is static in Java can be invoked as Classname.variablename or Classname.methodname or directly. It is not compulsory to invoke it only by using object name.
In interface, objects cannot be declared and static makes it possible to invoke variables just through class name without the need of object name.
final:
It helps to maintain a constant value for a variable as it can't be overridden in its subclasses.
This question already has answers here:
Why can't I define a static method in a Java interface?
(24 answers)
Closed 3 years ago.
There have been a few questions asked here about why you can't define static methods within interfaces, but none of them address a basic inconsistency: why can you define static fields and static inner types within an interface, but not static methods?
Static inner types perhaps aren't a fair comparison, since that's just syntactic sugar that generates a new class, but why fields but not methods?
An argument against static methods within interfaces is that it breaks the virtual table resolution strategy used by the JVM, but shouldn't that apply equally to static fields, i.e. the compiler can just inline it?
Consistency is what I desire, and Java should have either supported no statics of any form within an interface, or it should be consistent and allow them.
An official proposal has been made to allow static methods in interfaces in Java 7. This proposal is being made under Project Coin.
My personal opinion is that it's a great idea. There is no technical difficulty in implementation, and it's a very logical, reasonable thing to do. There are several proposals in Project Coin that I hope will never become part of the Java language, but this is one that could clean up a lot of APIs. For example, the Collections class has static methods for manipulating any List implementation; those could be included in the List interface.
Update: In the Java Posse Podcast #234, Joe D'arcy mentioned the proposal briefly, saying that it was "complex" and probably would not make it in under Project Coin.
Update: While they didn't make it into Project Coin for Java 7, Java 8 does support static functions in interfaces.
I'm going to go with my pet theory with this one, which is that the lack of consistency in this case is a matter of convenience rather than design or necessity, since I've heard no convincing argument that it was either of those two.
Static fields are there (a) because they were there in JDK 1.0, and many dodgy decisions were made in JDK 1.0, and (b) static final fields in interfaces are the closest thing java had to constants at the time.
Static inner classes in interfaces were allowed because that's pure syntactic sugar - the inner class isn't actually anything to do with the parent class.
So static methods aren't allowed simply because there's no compelling reason to do so; consistency isn't sufficiently compelling to change the status quo.
Of course, this could be permitted in future JLS versions without breaking anything.
There is never a point to declaring a static method in an interface. They cannot be executed by the normal call MyInterface.staticMethod(). (EDIT:Since that last sentence confused some people, calling MyClass.staticMethod() executes precisely the implementation of staticMethod on MyClass, which if MyClass is an interface cannot exist!) If you call them by specifying the implementing class MyImplementor.staticMethod() then you must know the actual class, so it is irrelevant whether the interface contains it or not.
More importantly, static methods are never overridden, and if you try to do:
MyInterface var = new MyImplementingClass();
var.staticMethod();
the rules for static say that the method defined in the declared type of var must be executed. Since this is an interface, this is impossible.
You can of course always remove the static keyword from the method. Everything will work fine. You may have to suppress some warnings if it is called from an instance method.
To answer some of the comments below, the reason you can't execute "result=MyInterface.staticMethod()" is that it would have to execute the version of the method defined in MyInterface. But there can't be a version defined in MyInterface, because it's an interface. It doesn't have code by definition.
The purpose of interfaces is to define a contract without providing an implementation. Therefore, you can't have static methods, because they'd have to have an implementation already in the interface since you can't override static methods. As to fields, only static final fields are allowed, which are, essentially, constants (in 1.5+ you can also have enums in interfaces). The constants are there to help define the interface without magic numbers.
BTW, there's no need to explicitly specify static final modifiers for fields in interfaces, because only static final fields are allowed.
This is an old thread , but this is something very important question for all. Since i noticed this today only so i am trying to explain it in cleaner way:
The main purpose of interface is to provide something that is unimplementable, so if they provide
static methods to be allowed
then you can call that method using interfaceName.staticMethodName(), but this is unimplemented method and contains nothing. So it is useless to allow static methods. Therefore they do not provide this at all.
static fields are allowed
because fields are not implementable, by implementable i mean you can not perform any logical operation in field, you can do operation on field. So you are not changing behavior of field that is why they are allowed.
Inner classes are allowed
Inner classes are allowed because after compilation different class file of the Inner class is created say InterfaceName$InnerClassName.class , so basically you are providing implementation in different entity all together but not in interface. So implementation in Inner classes is provided.
I hope this would help.
Actually sometimes there are reasons someone can benefit from static methods. They can be used as factory methods for the classes that implement the interface. For example that's the reason we have Collection interface and the Collections class in openjdk now. So there are workarounds as always - provide another class with a private constructor which will serve as a "namespace" for the static methods.
Prior to Java 5, a common usage for static fields was:
interface HtmlConstants {
static String OPEN = "<";
static String SLASH_OPEN = "</";
static String CLOSE = ">";
static String SLASH_CLOSE = " />";
static String HTML = "html";
static String BODY = "body";
...
}
public class HtmlBuilder implements HtmlConstants { // implements ?!?
public String buildHtml() {
StringBuffer sb = new StringBuffer();
sb.append(OPEN).append(HTML).append(CLOSE);
sb.append(OPEN).append(BODY).append(CLOSE);
...
sb.append(SLASH_OPEN).append(BODY).append(CLOSE);
sb.append(SLASH_OPEN).append(HTML).append(CLOSE);
return sb.toString();
}
}
This meant HtmlBuilder would not have to qualify each constant, so it could use OPEN instead of HtmlConstants.OPEN
Using implements in this way is ultimately confusing.
Now with Java 5, we have the import static syntax to achieve the same effect:
private final class HtmlConstants {
...
private HtmlConstants() { /* empty */ }
}
import static HtmlConstants.*;
public class HtmlBuilder { // no longer uses implements
...
}
There is no real reason for not having static methods in interfaces except: the Java language designers did not want it like that.
From a technical standpoint it would make sense to allow them. After all an abstract class can have them as well. I assume but did not test it, that you can "hand craft" byte code where the interface has a static method and it should imho work with no problems to call the method and/or to use the interface as usually.
I often wonder why static methods at all? They do have their uses, but package/namespace level methods would probably cover 80 of what static methods are used for.
Two main reasons spring to mind:
Static methods in Java cannot be overridden by subclasses, and this is a much bigger deal for methods than static fields. In practice, I've never even wanted to override a field in a subclass, but I override methods all the time. So having static methods prevents a class implementing the interface from supplying its own implementation of that method, which largely defeats the purpose of using an interface.
Interfaces aren't supposed to have code; that's what abstract classes are for. The whole point of an interface is to let you talk about possibly-unrelated objects which happen to all have a certain set of methods. Actually providing an implementation of those methods is outside the bounds of what interfaces are intended to be.
Static methods are tied to a class. In Java, an interface is not technically a class, it is a type, but not a class (hence, the keyword implements, and interfaces do not extend Object). Because interfaces are not classes, they cannot have static methods, because there is no actual class to attach to.
You may call InterfaceName.class to get the Class Object corresponding to the interface, but the Class class specifically states that it represents classes and interfaces in a Java application. However, the interface itself is not treated as a class, and hence you cannot attach a static method.
Only static final fields may be declared in an interface (much like methods, which are public even if you don't include the "public" keyword, static fields are "final" with or without the keyword).
These are only values, and will be copied literally wherever they are used at compile time, so you never actually "call" static fields at runtime. Having a static method would not have the same semantics, since it would involve calling an interface without an implementation, which Java does not allow.
The reason is that all methods defined in an interface are abstract whether or not you explicitly declare that modifier. An abstract static method is not an allowable combination of modifiers since static methods are not able to be overridden.
As to why interfaces allow static fields. I have a feeling that should be considered a "feature". The only possibility I can think of would be to group constants that implementations of the interface would be interested in.
I agree that consistency would have been a better approach. No static members should be allowed in an interface.
I believe that static methods can be accessed without creating an object and the interface does not allow creating an object as to restrict the programmers from using the interface methods directly rather than from its implemented class.
But if you define a static method in an interface, you can access it directly without its implementation. Thus static methods are not allowed in interfaces.
I don't think that consistency should be a concern.
Java 1.8 interface static method is visible to interface methods only, if we remove the methodSta1() method from the InterfaceExample class,
we won’t be able to use it for the InterfaceExample object. However like other static methods, we can use interface static methods using class name.
For example, a valid statement will be:
exp1.methodSta1();
So after looking below example we can say :
1) Java interface static method is part of interface, we can’t use it for implementation class objects.
2) Java interface static methods are good for providing utility methods, for example null check, collection sorting ,log etc.
3) Java interface static method helps us in providing security by not allowing implementation classes (InterfaceExample) to override them.
4) We can’t define interface static method for Object class methods, we will get compiler error as “This static method cannot hide the instance method from Object”. This is because it’s not allowed in java, since Object is the base class for all the classes and we can’t have one class level static method and another instance method with same signature.
5) We can use java interface static methods to remove utility classes such as Collections and move all of it’s static methods to the corresponding interface,
that would be easy to find and use.
public class InterfaceExample implements exp1 {
#Override
public void method() {
System.out.println("From method()");
}
public static void main(String[] args) {
new InterfaceExample().method2();
InterfaceExample.methodSta2(); // <--------------------------- would not compile
// methodSta1(); // <--------------------------- would not compile
exp1.methodSta1();
}
static void methodSta2() { // <-- it compile successfully but it can't be overridden in child classes
System.out.println("========= InterfaceExample :: from methodSta2() ======");
}
}
interface exp1 {
void method();
//protected void method1(); // <-- error
//private void method2(); // <-- error
//static void methodSta1(); // <-- error it require body in java 1.8
static void methodSta1() { // <-- it compile successfully but it can't be overridden in child classes
System.out.println("========= exp1:: from methodSta1() ======");
}
static void methodSta2() { // <-- it compile successfully but it can't be overridden in child classes
System.out.println("========= exp1:: from methodSta2() ======");
}
default void method2() { System.out.println("--- exp1:: from method2() ---");}
//synchronized default void method3() { System.out.println("---");} // <-- Illegal modifier for the interface method method3; only public, abstract, default, static
// and strictfp are permitted
//final default void method3() { System.out.println("---");} // <-- error
}