0

I'm trying to make a HttpServer in Java that reads the methods from a single class to try and make my code automatically adapt to changes, instead of having to copy/paste setHandler calls for every path I want.

To do this, I decided to try making a holder class with a field that one could use to call a method, and I wrote down an initialization function that loops through all methods in a "module," and then fills in the field that accepts the method. The problem is, for simplicity's sake, I typed the field as a FunctionalInterface with the corresponding types, but the compiler refuses to implicitly convert. Is there some kind of function, or cast that I gotta do?

This is the class

public class WebHandler {
    private String path;
    private ContentType type;
    private TriConsumer<Request, HttpServletRequest, HttpServletResponse> handler;

    public WebHandler(String path, ContentType type, TriConsumer<Request, HttpServletRequest, HttpServletResponse> handler) {
        this.path = path;
        this.type = type;
        this.handler = handler;
    }
}

This is the line that fails to compile (method is just a Method from reflection)

WebHandler newHandler = new WebHandler(annotation.path(), annotation.type(), method);

This line is part of the for loop that finds handler methods. method is the handler method it found and is trying to make a WebHandler with it.

As expected, the compiler complains about incompatible types. incompatible types: java.lang.reflect.Method cannot be converted to org.frostbytes.smmjam.util.TriConsumer<types ommitted for length>

In the end, what I want to do is to be able to call the function repeatedly with no reflection overhead after I've looked it up.

FrostBytes
  • 33
  • 4

1 Answers1

0

You're trying to pass TriConsumer into WebHandler, the problem is method isn't a TriConsumer. You have a reference to a method object. I'm guessing that's the accept() method or whatever for your triconsumer. Instead of passing that method, create an object from the TriConsumer class then pass that in. I'm not positive how you're creating the TriConsumer or getting the method so I can't tell you what to do for sure. If you show more information I can give more concrete information. But now here's a quick example

Class<? extends TriConsumer> cls; //you likely have this at some point
Method m = cls.getDeclaredMethod(Request.class, HttpServletRequest.class, HttpServletResponse.class); 

I'm guessing that m is what you're passing in. Instead what you want to is something like

Class<? extends TriConsumer> cls;
Constructor<? extends TriConsumer> cons = cls.getDeclaredConstructor(//cons args)
TriConsumer tc = cons.newInstance(//args); //pass this into the method
Matthew Kerian
  • 812
  • 5
  • 18
  • `method` is the method found by searching the "module," which is just a class with many functions programmed for handling http requests. I thought I put something different in the question, so I edited it to be more clear. – FrostBytes Jul 07 '19 at 02:55
  • It's still valid. You're getting a `Method` from reflection somewhere. What's the code where you get the method object from? – Matthew Kerian Jul 07 '19 at 02:56
  • yes, but what I want to do is be able to call the Method with a TriConsumer, instead of using `.invoke()`, I could use `.accept()` with the arguments. stack overflow guiding me through asking a question confuses me. A better way of saying what I want to do is to be able to call the function repeatedly with no reflection overhead after I've looked it up. – FrostBytes Jul 07 '19 at 02:58
  • Create whatever TriConsumer you need then cache it, don't look it up via reflection if it's already cached. Similar to lazy loading – Matthew Kerian Jul 07 '19 at 03:01
  • But I still want to be able to have it so I can just type methods in a class and the program automatically recognizes them as handlers. Not sure if this is the best way to go about this. – FrostBytes Jul 07 '19 at 03:09
  • @FrostBytes How does caching the tri-consumer stop you from doing that? I feel like you don't know what you want to do – Matthew Kerian Jul 07 '19 at 03:20