1

I'm currently working my way thorough Java Core book and I'm in the generic chapter. I can't grasp one thing here. As book states you cannot make a new object out of T in generic class, so this is not possible

public foo() { first = new T(); second = new T(); } //ERROR

What you can do is use functional interface and lambda expression with reference to constructor like this

foo<String> f = foo.makeFoo(String::new)

public static <T> foo<T> makeFoo(Supplier<T> constr)
{
    return new foo<>(constr.get(), constr.get());
}

And it's great, working as expected, but only with String, if I want to use with any other object, for example wrapped simple type Integer it's not possible. It gives me this error

Error:(35, 38) java: method makeFoo in class generic.foo<T> cannot be applied to given types;
required: java.util.function.Supplier<T>
found: Integer::new
reason: cannot infer type-variable(s) T
(argument mismatch; incompatible parameter types in method reference)

It seems only working with String and I have no idea why, I thought that it would work for every object

I'm trying to create all those objects on correct classes

  foo<String> fString = foo.makeFoo(String::new); //Works
  foo<Integer> fInteger = foo.makeFoo(Integer::new); //Doesn't work
  foo<Double> fDouble = foo.makeFoo(Double::new); //Doesn't work

EDIT

Actually this works with custom objects, only wrapped simple types won't compile

foo<MyCustomObject> fCustom = foo.makeFoo(MyCustomObject::new); //Works
3
  • 1
    The type of the variable f is foo<String>, so obviously it expects that the supplier returns a String object. Change it to foo<Integer> if you're giving it a supplier that returns an Integer object. Commented Dec 5, 2016 at 10:37
  • I'm doing exactly that and this gives cannot applied error. foo<Integer> fInteger = foo.makeFoo(Integer::new); Commented Dec 5, 2016 at 10:40
  • 1
    @MTomczyński I've rejected your edit of my answer as there was to much text/code I did not write. I think it would be better if you would have posted it as your own answer to your question, this is absolutely appropriate. Commented Dec 5, 2016 at 11:08

2 Answers 2

3

In contrast to String, there is no no-arg constructor of Integer. So Integer::new is not a Supplier<Integer>. makeFoo(Object::new) would work.

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

Comments

1

As lexicore pointed we cannot make expression Integer::new, due to no no-arg constructor of Integer object. Correct syntax with integer can be as simple as this, where arg being int variable

foo<Integer> f = foo.makeFoo(() -> (arg));

Wrapping in new Integer(arg) is unnecessary here.

More info on the topic: Java 8 Supplier with arguments in the constructor

Comments

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.