Home > Blockchain >  Java - static method in an interface - What do I need to do?
Java - static method in an interface - What do I need to do?

Time:02-26

The details:

I have been given a Java program in which I need to fill in some code. The main idea of the program is to get used to interfaces and static methods in them. For the past 6 hours I have been watching countless of videos regarding interfaces and static interfaces and I still feel somewhat clueless to what I am supposed to do.

public interface Util {

    static Util create() {
        //TODO: this line needs to be replaced with the constructor of a concrete implementation 
        throw new IllegalStateException("Not implemented yet!");
    }
    Instruction forSymbols(Symbol first, Symbol last);
    
    Symbol forToken(String token);

    Supplier<Integer> buildPipe(InputStream input);

    Consumer<Integer> buildPipe(OutputStream output);

    String getInstructionCode(Instruction instruction);

    Optional<Instruction> getInstruction(String code);
}

This is a snippet of the util interface for a program that will be relevant for having a Ook! translator and is supposed to have a lot of useful tools for other classes.

Now, my goal is to understand what I am supposed to do.

What I tried:

Considering I don't know what I need to do, I don't know what I have to code. I understand that an interface is a sort of template for classes. A static method in an interface is the part that I don't understand yet: I have been told that a static method in an interface is something that doesn't have to be implemented in other classes. In my case, the static method create() is "supposed to be a concrete instance of the util object". So, if I get this right, due to it being static, there would be one shared instance of util.

Afterwards, if a class has the prompt "Instruction instruction = util.forSymbols(Symbol.Point, Symbol.Point);" after Util.create() has been used, I would have defined instruction using util's forSymbols method.

I do not know if I am good at conveying just what I need. I per sé understand what a constructor is, I understand what an interface is, I understand what static does, but I don't understand what I have to insert into the create() method. Heck, I don't even want a direct code solution to my problem, I just want to understand what I am supposed to code.

That being said, if anyone could give me an example of an interface working in a similar fashion as my code above that makes it clear just what exactly the static part in an interface does aswell as help me out with my describes issues, I would be tremendously thankful. Also, I hope that my issue description is alright.

That being said, thank you for trying to help me and thanks to all possible answers.

CodePudding user response:

No, the interface can't keep state, so there isn't anywhere for the shared instance to hang out. This is not a way to implement a singleton. It must be a factory method. I think adding a method like this is confusing and probably a bad idea because it ties together the interface and the implementation in an inflexible way. you're expected to create something that implements Util, so there is going to be a constructor call for that class implementing Util. Otherwise it's not clear.

Another sign this is a bad idea is obviously Util doesn't have any instance methods so isn't usable as an object; either a) there is no state and creating an object is pointless or b) the object returned has to be cast to something else to be useful. Casts are bad, for the most part; they mean we're not benefiting from using the type system.

An interface is like a mask an object wears to keep users of it from seeing anything on it except what is on the interface. But allowing static methods is kind of a bolted-on feature that doesn't have much to do with interfaces (except that classes that implement the interface can call them without having to reference the interface).

Originally in Java you could put static methods only in classes, not in interfaces. There was an idea of a utility class, which was just a dumping ground for people to put static methods, and which didn't have any purpose as a class otherwise. Then there was a change to the language so you can put static methods on interfaces and not have to have a class involved. That's all putting static methods on an interface buys you, you can add only static methods because there is no mutable state allowed.

These methods outlined for you should all be things you can implement with only passed in arguments and local variables, without keeping any state outside of the scope of the method implementation.

I've tried to give you some idea of what is possible and what isn't, once that is clear you can ask your instructor some more focused questions about what you need to do.

CodePudding user response:

I agree with Nathan Hughes. This an ill-conceived design, on the face of it.

But to cut to the chase, here is an example of you could complete that static method:

   static Util create() {
       return new OookUtil();
   }

where

   public class OookUtil implements Util {
       public OookUtil() { ... }
       // methods implementing the Util API for the Oook case.
   }

Reviewing this we can immediately see one of the problems with the interface design. We have hard-wired a specific implementation class into the interface. That is most likely a bad idea.

Could we do any better? Well ... maybe ...

The Java SE class libraries have a concept of a Java Service Provider Interface or SPI. An SPI allows different providers to be selected depending on what is available at runtime, and so on. The idea is that SPI code does a runtime classpath search looking for all classes that implement the SPI (e.g. your Util). Then it selects the "best" according to (typically) runtime configurable criteria.

That logic would be implemented in your create method. The method would then instantiate the chosen class reflectively and return the instance. In its simplest form (ignoring the classpath search aspect) it might be something like this:

   static Util create() {
       String classname = System.getProperty("yourapp.utilclass");
       Class<?> clazz Class.forName(className);
       return (Util) clazz.newInstance();
   }

In this illustration are getting a classname from the system properties. It could be set by running the application with a -D option; e.g. -Dyourapp.utilclass=yourapp.OookUtil.

The above code needs some exception handling ... which I will leave for you to figure out.

Maybe that is what your instructor is getting at. But if so, he or she should have explained more clearly what was expected.

  • Related