8

Java is often (rightly IMHO criticized) for overusing the class keyword, as it can denote:

  1. a factory to instantiate objects (traditional classes)
  2. a collection of global methods (when all methods are static and there is a private constructor...the so-called "utility class" pattern)
  3. an application (when it holds a public static void main method, etc)
  4. a wrapper for a singleton

Now several Java successors have gone with top-level object keyword to avoid the singleton usage (getting rid of #4, which is good), and Java itself, many years ago, allowed the interface to include static methods to get rid of the ugly #2.

But since #3 in the list above is a special case of #2, why not adopt the interface for applications? For example:

interface GreeterApp {
  static void main(String[] args) {
    System.out.println("Hello world");
  }
}

works just fine:

$ java GreeterApp‍.java
Hello world

I have not seen this pattern used before, but my web searching skills might need some work. But doing so allows use to use the class keyword only for factories that instantiate objects, and to use interface for collections of (static) methods, since the complaint about traditional Java application classes is that they really existed only to "house" the main method.

It may be that the use of class for a main app is so widespread, and so traditional, that the use of an interface to house an application's main method might never have been considered. (EDIT: But see Jörg W Mittag's note in the comments that indeed the JLS authors were aware.)

But there may be more technical reasons for using classes over interfaces, or interfaces over classes, other than linguistic preferences. Are there any "kinds" of applications that call out for one or the other?

(EDIT: The question was slightly reworded to remove the opinionated tone and instead ask for specific advantages.)

9

4 Answers 4

2

Until relatively recently, you could not define a concrete method on any interface in Java. Class was the only option. It never occurred to me to define main on an interface since that has been allowed (1.8, IIRC). One minute ... OK yes, that works.

It seems you can use an interface to hold your main method if you like. As for advantages, I don't see any, really. static variables and methods and variables in Java are effectively procedural. That is, they can't be overridden, only hidden and therefore do not support sub-typing polymorphism. In essence, public static methods are globally defined (with some esoteric caveats.)

The only thing that would change if you define your main method on an interface instead of a class is that anything else defined in that 'type' would need to be public. You would also not be able to define a constructor on that type. If all your application classes do is hold a single main method, then it really doesn't matter which you choose. There's literally no difference (to my knowledge) between a public static method defined on an interface and one defined on a class. Whatever floats your boat, I suppose.

But to join the chorus: you are overthinking things a bit. The main method is basically a convention. When the JVM starts, it needs an entry point. That was the one James Gosling chose. Ultimately the answer is, defining main on a class was the only option for most of Java's history and there's no clear reason to use an interface but if you prefer it, I don't see a problem with it aside from the fact that it will be surprising to people.

1
  • I was looking for (and tbh expecting) something like this: the answer to whether there were any technical reasons to use one over the other appears to be "no" and stylistically the only real concern is "class" is less surprising. I am aware the the "utility class" pattern isn't going away; some of Java's successors have wisely done away with it IMHO :)
    – Ray Toal
    Feb 4, 2023 at 2:53
1

A class represents an actual entity in code. It provides the implementation for your code and the ability to define implementations on an interface is actually relatively new (e.g. default implementations). Yes you can have static members on an interface but typically the static main method is just there for some initialization to get an actual instance of your application up and running. By using an interface, you're vacating all the abilities defining and working with members that don't exist on an interface. An interface is intended to provide the definition of the interaction pattern and not it's implementation. Default methods implementations are a modern convenience and static members are very uncommon. They should be named as adjectives as they describe the behavior the class provides.

In Java, you're supposed to prefer interaction classes via the interface so that implementations can be easily changed without having to change all the references to the functionality. You can also provide more granularity with interfaces, only exposing clients of your classes to what they need.

Some recommended reading to help understand the role of interfaces and how to leveraged them effectively:

https://dev.to/kylec32/effective-java-tuesday-prefer-interfaces-to-abstract-classes-21cn https://stackify.com/interface-segregation-principle/

1

Class and interface are both concepts that have additional aspects, facets. More than is needed for a program's static entry point main.

The only overhead of a class is its object instantiation. But a program often benefits from instantiating a singleton. Not only less "static" and fields, but also the multiple document interface: a second start of a program with an other (file) parameter can pass that file to the first program to open a second window. And exit the second program.

A class fits handling an application.

An interface: if you want some extra small private (static) bottom-up functions, it becomes awkward.

Also mind, that the interface was introduced as remedy against multiple inheritanc, and nowadays is quite complex. It no longer is a simpler notion. When you read "class" on the other hand, no box of use cases is opened.

0

There are several scenarios, where using an interface can be an advantage. Two obvious ones are:

  1. The class already extends some other base class
  2. The need of supporting multiple interfaces at once

Since interfaces are supporting implementations nowadays using the default keyword, I tend to default to interfaces and only introduce abstract classes, when I need to preserve a state in class variables or I need to use field dependency injection in Spring with @Autowired.

2
  • 1
    Those are the same scenario Feb 4, 2023 at 1:33
  • @user253751 I agree, the lack of multi-inheritance is the common baseline here. But I've provided both intentionally, as in the first scenario I had in mind that you use the interface to circumvent the fact that there is an existing base class already, while in the second szenario you share one implementation with multiple interfaces Feb 4, 2023 at 8:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.