0

I'm struggling with a little java trick which is: how to pass a non void method with one parameter as a parameter (or two) of another method ? I guess this will involve Function or Biconsumer, and I've been trying with it. But I didn't manage to make it work... The exact context is quiet simple: I'm working on Fix messages with Quickfixj librairy and I need to call in the class Message:

  • getInt(int tagValue) returning an int,
  • getString(int tagValue) returning a String,
  • getChar(int tagValue) returning a char.

I've been trying this:

public static < T > void setFieldsMap(int fieldTag,
                                          Function< Integer, T > messageGetter,
                                          String fieldKey ) throws FieldNotFound {
            this.fieldsMap.put( fieldKey, String.valueOf( messageGetter.apply( fieldTag ) ) );
}

Which I wanted to call like that:

setFieldsMap( myTag, message::getString, "MY_KEY" );

But this doesn't compile. I'm getting the following error: "int is not a functional interface".

Of course I already checked Google but it didn't give me a fitting solution. I only found solution to call a method without parameter.

I've been using Function to call a getter without parameter, or Biconsumer to call a setter with a parameter. But it seems that calling a non void method with one parameter isn't that easy...

Does anyone has a clue to make this work? Thanks a lot for your time and your help guys! :)

2
  • What's fieldsMap and why would it accept a random T as a value? Commented Jun 30, 2020 at 6:07
  • The first test to expose a misuse of a method reference is to try to create a variable in an assignment context: Function<Integer, T> messageGetter = message::getString; (substituting the concrete type for whatever T is). This moves it out of potentially tricky contexts and tells you where the problem is. Commented Jun 30, 2020 at 6:13

2 Answers 2

2

At the current form the code won't compile because you can't really access this. from the static method.

Other than that you can start off with the following (I've removed the irrelevant parts):

class Sample {
    public static < T > void setFieldsMap(int fieldTag,
                                         Function< Integer, T > messageGetter,
                                         String fieldKey )  {
         messageGetter.apply(fieldTag);

    }

}
public class SampleTest {

    private static String toString(Integer  val) { // an example of method
        System.out.println("Converting " + val);
        return val.toString();
    }
    public static void main(String[] args) {
        Sample.setFieldsMap(123, SampleTest::toString, "someKey");
    }
}

Another point to consider is that T is not really used, so it can be substituted with ?

class Sample {

    public static void setFieldsMap(int fieldTag,
                                    Function< Integer, ? > messageGetter,
                                    String fieldKey )  {
         messageGetter.apply(fieldTag);

    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, it seems to be working! Unfortunately I still have a pb with the handling of an exception that my method is supposed to throw. But it seems I'm obliged to surround each invocation of this method with a try/catch. Otherwise it doesn't compile..
2

You method input argument Function< Integer, T > messageGetter means that you have to supply a function or method reference that takes an Integer as input and returns T as output.

The method reference message::getString is not a valid input argument, because getString(String s) takes a String as input, not an Integer.

Just imagine if you could supply that argument, then the method's implementation messageGetter.apply(fieldTag) would essentially read as message.getString(fieldTag), which would not work, because fieldTag is an int.

2 Comments

actually, getString() takes a int as parameter. It is named as getString because it returns a String. quickfixj.org/javadoc/1.6.3/quickfix/…
Well, then your remark "getString(String s) returning a String" in the original question is misleading...

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.