Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Methods that return Lambdas Problem #19

Closed
mortdiggiddy opened this issue Feb 10, 2016 · 3 comments
Closed

Methods that return Lambdas Problem #19

mortdiggiddy opened this issue Feb 10, 2016 · 3 comments

Comments

@mortdiggiddy
Copy link

Hello,

Great work, truly great.

I noticed a problem when I tried to use this library for the first time. Consider the following code:

public class TestPredicate {
    public static Predicate<Method> withModifiers(int modifier) {
        return m -> m.getModifiers() == modifier;
    }

    public static void main(String[] args){
        Predicate<Method> a = withModifiers(1);
        Class<?> type = TypeResolver.resolveRawArgument(Predicate.class, a.getClass());

        System.out.println(type);
    }
}

Produces console ouput:
class java.lang.Integer

This is wrong, it should produce class java.lang.reflect.Method. I noticed that nested way deep in the code of populateLambdaArgs(...) that it does indeed find a TypeVariable of java.lang.reflect.Method. However this fails the test at the end of the method:

for (int i = 0; i < arguments.length; i++)
    if (paramTypeVars[i + offset] instanceof TypeVariable)
        map.put((TypeVariable<?>) paramTypeVars[i + offset],     
                        arguments[i].getType(lambdaType.getClassLoader()));
             break; 

When the main() method is changed above to this:

public static void main(String[] args){
        Predicate<Method> a = m -> m.getModifiers() == 1;
        Class<?> type = TypeResolver.resolveRawArgument(Predicate.class, a.getClass());

        System.out.println(type);
}

Everything works. class java.lang.reflect.Method

@mickare
Copy link

mickare commented Feb 11, 2016

Hi mortdiggiddy! :)

So short story first:
It seems to me that you have a version before the latest commit.
The commit is unfortunately not yet on Maven Central. I'm also waiting on it. ^^

The long version:
I just tested the code on the top with the latest commit and it returned the class Method.
#16

I can tell you how java passes the modifier Integer to the predicate.

In the default use-case of methods, arguments that are passed to a method are in following order: this (if static = null) and then the arguments that are defined in the method header.
In this case it is only Method.

But if you use variables from the outside in a lambda function, Java passes them into the lambda expression by automatically inserting them as arguments behind "this".

The old TypeResolver did not considered that new feature of Java 8.

I hope I could describe a little bit the background story.

So basically in your second code example you don't pass any variables into the lambda expression. That's why it is working.

mickare added a commit to mickare/typetools that referenced this issue Feb 11, 2016
@jhalterman
Copy link
Owner

@mortdiggiddy Try the latest release, 0.4.5. This should work as expected in the latest release. Feel free to re-open if this is not the case. Also see the test I added based on your example:

https://github.com/jhalterman/typetools/blob/master/src/test/java/net/jodah/typetools/issues/Issue19.java

jhalterman added a commit that referenced this issue Mar 30, 2016
@mortdiggiddy
Copy link
Author

Good work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants