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

TypeResolver.resolveRawArgument returns java.lang.Object instead of actual type ? #14

Open
pderop opened this issue Dec 3, 2015 · 6 comments · Fixed by #17
Open

TypeResolver.resolveRawArgument returns java.lang.Object instead of actual type ? #14

pderop opened this issue Dec 3, 2015 · 6 comments · Fixed by #17
Labels

Comments

@pderop
Copy link
Contributor

pderop commented Dec 3, 2015

Hi;

I'm having (for example) the following interface:

public static class Printer<T> {
    public void print(T t) {
        ...
    }
}

Now, let's define a method reference on the "print" method, and using an instance of the Printer class:

Printer<String> printer = new Printer<>();
Consumer<String> print = printer::println;
Class<?> type = TypeResolver.resolveRawArgument(Consumer.class, print.getClass());
System.out.println(type); // prints "java.lang.Object" instead of "Printer" ?

so, above, I would expect to get a Printer type instead of Object ?

Notice that the following similar example is working fine:

Consumer<String> print = System.out::println;
type = TypeResolver.resolveRawArgument(Consumer.class, print.getClass());
System.out.println(type); // "java.lang.String"

Am I missing something ?

thanks in advance;
/Pierre

@pderop
Copy link
Contributor Author

pderop commented Dec 3, 2015

I forgot to say that I'm using the following java version:

java -version

java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)

@pderop
Copy link
Contributor Author

pderop commented Dec 3, 2015

errata, (oops sorry):

for the following example:

Printer<String> printer = new Printer<>();
Consumer<String> print = printer::println;
Class<?> type = TypeResolver.resolveRawArgument(Consumer.class, print.getClass());
System.out.println(type);

I would expect the type to be "java.lang.String" instead of "Java.lang.Object".

thanks
/Pierre

@mickare
Copy link

mickare commented Jan 7, 2016

This seems to be similar to my #16?

I would explain this here that the object printer is taken as first parameter into the new created lambda expression printer::println as local variable. Then the TypeResolver finds the class both Printer and String share, which is Object.
Could this theory be true?

@jhalterman
Copy link
Owner

The short answer is that this use case does not appear to be supported by the technique we're using to resolve lambda type information. The reason is, with:

Printer<String> printer = new Printer<>();
Consumer<String> print = printer::println;

The argument for println is defined as String on the Printer<String> variable declaration. At runtime though, variable declarations are erased, so this just becomes Printer and the String is lost. It is similar to:

Consumer<String> print = System.out::println;

The difference is here the value of T is explicitly defined on the System.out.println method definition as a String rather than as T.

@yaitskov
Copy link

Hi,

I am facing this issue.

Consumer<Integer> c = System.out::println ; // not working it returns Object instead of Integer

work around is

Consumer<Integer> c = (Integer x) -> System.out.println(x);

@jhalterman
Copy link
Owner

Hi @yaitskov,

What's interesting about your scenario is that this works:

Consumer<String> print = System.out::println;

But this doesn't:

Consumer<Integer> print = System.out::println;

For whatever reason the ConstantPool, which is where we read lambda/method ref type information, encodes the latter scenario as println(Object o). It might be hard for us to recognize that in this scenario Object should actually be String since we're converting from another type. Perhaps we can detect that, but will need some further investigation.

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

Successfully merging a pull request may close this issue.

4 participants