Type inference for generic parameters when calling a method

I was making a class with builder-type setters for generic member variables and I noticed something when I tried to pass it to a function accepting an object with a specialized generic argument for that type via new. Mainly this:
public static void bar(Foo<Integer> f){}
public static class Foo<T>{
Foo<T> self(){
return this;
}

}
public static void main(String[] args) {
bar(new Foo<>().self()); //gives an error, because new Foo<>().self() returns Foo<Object>
}
public static void bar(Foo<Integer> f){}
public static class Foo<T>{
Foo<T> self(){
return this;
}

}
public static void main(String[] args) {
bar(new Foo<>().self()); //gives an error, because new Foo<>().self() returns Foo<Object>
}
It appears that the compiler cannot infer the type of new Foo<> unless it's specifically told that it's new Foo<Integer> first off...why? Is the java compiler stupid or something? second off is there a way around this? Because in my case the generic argument is a little long and looks very ugly.
8 Replies
JavaBot
JavaBot2w ago
This post has been reserved for your question.
Hey @nikcho-kouhai! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically marked as dormant after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
rb5500
rb55002w ago
Okay Why Can't the Compiler Infer the Type?
nikcho-kouhai
nikcho-kouhaiOP2w ago
that's what I want to know..
Itsurran
Itsurran2w ago
There are several approaches to work around this limitation: Explicit Type Declaration: The simplest way is to explicitly specify the type when creating the instance: java bar(new Foo<Integer>().self()); Factory Method: You can create a factory method that returns a Foo<T> with a specific type: java
public static <T> Foo<T> createFoo() {
return new Foo<>();
}

public static void main(String[] args) {
bar(createFoo());
}
Static Method for Type Inference: If you want to avoid repeating long generic types, you could define a static method that encapsulates the creation logic:
java
public static Foo<Integer> createIntegerFoo() {
return new Foo<>();
}

public static void main(String[] args) {
bar(createIntegerFoo());
}
public static <T> Foo<T> createFoo() {
return new Foo<>();
}

public static void main(String[] args) {
bar(createFoo());
}
Static Method for Type Inference: If you want to avoid repeating long generic types, you could define a static method that encapsulates the creation logic:
java
public static Foo<Integer> createIntegerFoo() {
return new Foo<>();
}

public static void main(String[] args) {
bar(createIntegerFoo());
}
These methods allow you to maintain clarity in your code while still leveraging generics effectively without cluttering your main logic with verbose type specifications. By using these techniques, you can streamline your code and avoid the verbosity of specifying long generic types repeatedly while ensuring that the compiler understands what types you are working with.
This message has been formatted automatically. You can disable this using /preferences.
rb5500
rb55002w ago
Did you fix it now?
nikcho-kouhai
nikcho-kouhaiOP2w ago
well I do know if I tell it what the type is it's gonna work either via <Integer> in the brackets or a method that returns that type. It just kind of bugs me that I have to do that I suppose there is probably no other way to do it. An odd limitation of the compiler for some reason thanks for the suggestion anyway
JavaBot
JavaBot2w ago
If you are finished with your post, please close it. If you are not, please ignore this message. Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.
JavaBot
JavaBot2w ago
Post Closed
This post has been closed by <@359755548973072397>.

Did you find this page helpful?