samedi 21 mars 2015

Use of generics in a final method that returns a value of the same type of its object

Consider the following immutable classes:



A
B extends A
C extends B
D extends C
...


Class A has a method called process that gets a parameter of type A, and then returns a value of the type of the calling object:



public class A {

public final <T extends A> T process(A a) {
Class clazz = getClass();
T result = createObjectOfType(clazz);
return result;
}
}

public class B extends A { }

public class C extends B { }


This is the (very simple) test code:



public void test()
{
A a = new A();
B b = new B();
C c = new C();

// Returns type A:

A resultAAA = a.process(a); // Works.
A resultAAB = a.process(b); // Works.
A resultAAC = a.process(c); // Works.

B resultAAA = a.process(a); // Runtime error.
B resultAAB = a.process(b); // Runtime error.
B resultAAC = a.process(c); // Runtime error.

C resultAAA = a.process(a); // Runtime error.
C resultAAB = a.process(b); // Runtime error.
C resultAAC = a.process(c); // Runtime error.

// Returns type B:

A resultBBA = b.process(a); // Works.
A resultBBB = b.process(b); // Works.
A resultBBC = b.process(c); // Works.

B resultBBA = b.process(a); // Works.
B resultBBB = b.process(b); // Works.
B resultBBC = b.process(c); // Works.

C resultBBA = b.process(a); // Runtime error.
C resultBBB = b.process(b); // Runtime error.
C resultBBC = b.process(c); // Runtime error.

// Returns type C:

A resultCCA = c.process(a); // Works.
A resultCCB = c.process(b); // Works.
A resultCCC = c.process(c); // Works.

B resultCCA = c.process(a); // Works.
B resultCCB = c.process(b); // Works.
B resultCCC = c.process(c); // Works.

C resultCCA = c.process(a); // Works.
C resultCCB = c.process(b); // Works.
C resultCCC = c.process(c); // Works.

}


I want to modify the source code to convert those runtime errors into compile time errors or warnings, without having to overload or override the process method.


However, the test code must not change (no casts or generic parameters).


Aucun commentaire:

Enregistrer un commentaire