Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics: Use this type as return type?

I'm trying to make an API as user friendly as possible.

Let's have:

class B extends A {}

class A {
    A setX(){ ...; return this; }
}

Now this

B b = new B().setX();

is invalid, has to be casted:

B b = (B) new B().setX();

Is there a way using generics in A to make compiler aware of "this" type and accept the first way - without casting and without passing type parameter at the place where used? (I.e. not new B<B>().setX(), that's ugly.)

I KNOW why Java needs retyping in this case. Please no answers explaing that setX() returns A. I know that. I am asking if generics can solve this.

And for those still wanting to tell me that "this is how static typing works" and "not even generics can help with that", consider this valid Java code:

Map<String, String> map = new HashMap(){{ put( "foo", new RuntimeException() );
String foo = map.get("foo");  // ClassCastException!!

So you can see that generics DO allow you get a CCE without actual type cast appearing in the code.
That's the reason why I expect generics to allow getting rid of the explicit type cast.

Also, IIRC C++ allows that.

like image 699
Ondra Žižka Avatar asked Jun 16 '13 23:06

Ondra Žižka


People also ask

Can Java return type be generic?

So methods of generic or nongeneric classes can use generic types as argument and return types as well. Here are examples of those usages: // Not generic methods class GenericClass < T > { // method using generic class parameter type public void T cache ( T entry ) { ... } }

Why don t Java generics support primitive types?

Type safety is verified at compile time, and runtime is unfettered by the generic type system. In turn, this imposed the restriction that generics could only work over reference types, since Object is the most general type available, and it does not extend to primitive types.


1 Answers

Try this in class A:

public <T extends A> T setX() {
    return (T) this;
}

And you can use it like this

B b = new B().setX();
like image 139
Golyo Avatar answered Oct 09 '22 22:10

Golyo