helper function for default interface method - java

I need to incorporate some helper methods to assist the default method of interface on Java 8 - for better code organization.
So the only available option seems to be to qualify them with 'static' - and thus leave them exposed to outside.
Is there a better way to achieve this - migrating to Java 9 is not an option.

If upgrading to a more recent version is an option for you, you may in fact be able to use private methods in an interface
In Java 9 and newer, interfaces allow private (non-abstract) methods. See JSL 9.4:
A method in the body of an interface may be declared public or private (§6.6). If no access modifier is given, the method is implicitly public...
And these private methods may be static too (same source):
...It is permitted for an interface method declaration to contain both private and static.
If you have to stay on Java 8, you could use package-private classes and methods (yes, this is not private to the type, but package-private is a better alternative)
public interface Interface {
default void doSomething() {
InterfaceHelper.doSomething();
}
}
class InterfaceHelper {
static void doSomething() { //package-private class and method
}
}

Related

Java 9 Interface : Why default Modifier Converted into public Modifier

My Question is about interface. I create an interface and define four methods: first method is a private method; second is a default method; third is a static method; and fourth is an abstract method.
After compiling this interface and checking its profile: the default method is converted into a public method, and both the static and abstract methods have a prepended public modifier. Why is this?
Code:
interface InterfaceProfile {
private void privateM() { //this method is hidden
System.out.println("private Method");
}
default void defaultM() {
System.out.println("Default Method");
}
static void staticM() {
System.out.println("Static Method");
}
void doStuff(); //by default adds the public modifier
}
InterfaceProfile class
D:\Linux\IDE\Workspace\OCA-Wrokspace\Ocaexam\src>javap mods\com\doubt\session\InterfaceProfile.class
Compiled from "InterfaceProfile.java"
interface com.doubt.session.InterfaceProfile {
public void defaultM();
public static void staticM();
public abstract void doStuff();
}
The fact that it's a default method doesn't make a difference. The implicit scope is public.
Here's what the tutorial says:
All abstract, default, and static methods in an interface are implicitly public, so you can omit the public modifier.
Simple: by default, all methods in an interface are public. You can restrict that by applying private, but whenever you do not do that, that default kicks in. Thus: there is no conversion taking place at all.
Quoting the Java Language Specification:
A method in the body of an interface may be declared public or private (§6.6). If no access modifier is given, the method is implicitly public. It is permitted, but discouraged as a matter of style, to redundantly specify the public modifier for a method declaration in an interface.
( the ability to have private methods in interfaces was introduced with Java 9, as people discovered that Java 8 default methods often created the need to have, well, private methods that such default methods could make use of, without making these helper methods publicly visible )
The default modifier is public, because that is how the interface declaration is defined:
https://docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
If you are asking for the reasoning behind this, i would argue that the purpose of defining an interface is to ensure the - well - interface of all implementing classes, meaning that all implementing classes have clear contracts on which public accessable methods they need to provide.
Adding private methods to an interface does not serve this primary purpose and seems to be more of an implementation hint. Private and abstract methods were late additions to interfaces.
Related: Should methods in a Java interface be declared with or without a public access modifier?
https://docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
All abstract, default, and static methods in an interface are implicitly public, so you can omit the public modifier.
In effect, a class that implements an interface exposes all of the interface methods (other than private) to any other code that has visibility of the class.
It would be very confusing if a class had an interface but the methods on the interface would be visible to some code and not other. If you want to selectively expose methods, then you should probably make use of multiple interfaces.
public interface Profile {
generalMethod() ...
}
public interface SecretProfile extends Profile {
secretMethod() ...
}
Classes may choose to implement either of the interfaces (or even both). 3rd party code can check for the presence of the interface and know that the method is available or not.

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);
}

default methods in interface but only static final fields

I understand that all fields in an Inteface is implicitly static and final. And this made sense before Java 8.
But with the introduction of default methods, interfaces also have all the capabilities of an abstract class. And hence non-static and non-final fields are also necessary.
But when I tried declaring a field normally, it became static and final by default.
Is there a way to declare a non-static and non-final field in Interface in Java 8.
Or am I totally misunderstanding something here???
All fields in interfaces in Java are public static final.
Even after addition of default methods, it still does not make any sense to introduce mutable fields into the interfaces.
Default methods were added because of interface evolution reasons. You can add a new default method to the interface, but it only makes sense if the implementation uses already defined methods in the interface:
public interface DefaultMethods {
public int getValue();
public default int getValueIncremented() {
if (UtilityMethod.helper()) { // never executed, just to demonstrate possibilities
"string".charAt(0); // does nothing, just to show you can call instance methods
return 0;
}
return 1 + getValue();
}
public static class UtilityMethod {
public static boolean helper() {
return false;
}
}
}
No - in Java 8 all fields are static and final as in previous Java versions.
Having state (fields) in an interface would raise issues, in particular with relation to the diamond problem.
See also this entry that clarifies the difference between behaviour and state inheritance.
I strongly do not recommend to do that. Use abstract classes instead. But if you really need it you can do some workaround trick with some wrapper class. Here is an example:
public interface TestInterface {
StringBuilder best = new StringBuilder();
default void test() {
best.append("ok");
System.out.print(best.toString());
}
}
No - In java 8 you can't have not public static final fields in interfaces, unfortunately.
But I hope in the future this will be added to the language.
Scala allows interface with not static fields, and this opens up so many more possibilities for code reuse and composition than available in Java 8

Methods visibility in interface

Do all methods in an Interface has by default Public visibility mode?
All methods in an interface default to public.
See Java Language Specification 6.6.1 which states
All members of interfaces are
implicitly public.
All interface methods ARE public abstract, all interface fields are public static final...
see here.
Just to add to other answers here: all methods are public, however, if the interface itself is package-local then effectively all methods are also package-local.
You can therefore mix public and package-local methods, by making a package-local interface extend a public one.
public interface P{
void iAmPublic();
}
interface L extends P{
void iAmPackageLocal();
}
Here L effectively has one public and one package-local method. Clients from outside the package will only see iAmPublic(), whereas ones from inside the package will see both methods.
In the same way you can nest interfaces inside other classes to achieve even tighter method visibility.
Yes, all methods of an interface are public, and can't have any other access modifier (i.e. the default public access modifier is the only valid access modifier)
Yes, all methods in an interface are implicitly public and abstract.
Check Java language specification chapter 9.4

Why no static methods in Interfaces, but static fields and inner classes OK? [pre-Java8] [duplicate]

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
}

Categories