M Tomczynski
M Tomczynski

Reputation: 15714

Java generic object with lambda expressions

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

Upvotes: 1

Views: 1173

Answers (2)

M Tomczynski
M Tomczynski

Reputation: 15714

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

Upvotes: 1

lexicore
lexicore

Reputation: 43661

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.

Upvotes: 3

Related Questions