Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

overload method with same generic parameter?

Tags:

java

generics

I know that I can't do this:

public abstract class DTODomainTransformer<T, S> {

    public abstract S transform(T);

    public abstract T transform(S);

} 

Because I get the compiler complaint:

Method transform(T) has the same erasure transform(Object) as another method in type Transformer<T,S>

I understand that is because both T and S could be extending same class. So doing this way i can tell him "No, they are not the same, so take it easy"

public interface Transformer<T extends AbstractDTO , S extends AbstractDomain> {

    public abstract S transform(T object);

    public abstract T transform(S object);

}

Then, my question is, is there any way to tell the compiler that T and S extend from different classes without telling which ones in concrete? I mean, in this last case, I've specified which classes had to be T and S (extending respectively). But what if I want it more generic and not specify them? I'd like to tell the compiler, "Hey, compiler, T and S are not the same! They are different classes. I don't know exactly which classes they are, but I'm sure that they are different".

like image 610
jscherman Avatar asked Mar 19 '15 20:03

jscherman


People also ask

Can overloading have same parameters?

No, you cannot overload a method based on different return type but same argument type and number in java. same name. different parameters (different type or, different number or both).

Does method overloading allow same member name with different parameters?

i.e. the methods can have the same name but with different parameters list (i.e. the number of the parameters, the order of the parameters, and data types of the parameters) within the same class.

Can a generic function be overloaded?

Answer: Yes, we can overload a generic methods in C# as we overload a normal method in a class.

Can overloaded methods have the same method signature?

Method overloading is possible only if the overloaded methods have different signatures. It cannot be possible if the signature is same and only the return type is different.


1 Answers

There's not an obvious way. (Although you can build one, as I show below.)

This overload rule is due to a limitation of how the supertype (in this case, interface) that declares the overloads gets translated (by erasure) to bytecode.

If there's a generic parameter declared T, a method that uses T in its signature will have bytecode generated as the upper bound of T, for example

class Generic<T> {
    void work(T t) {}
}

will get erased to

class Generic {
    void work(Object t) {}
}

and

class Generic<T extends Number> {
    void work(T t) {}
}

will get erased to

class Generic {
    void work(Number t) {}
}

This is how the bounded example works, because the overloads erase differently.

public interface Transformer {
    public abstract AbstractDomain transform(AbstractDTO object);
    public abstract AbstractDTO transform(AbstractDomain object);
}

But without specific bounds, what erased bytecode should be generated for the overloaded methods?

So your T and S being different on the subtype is not what's important. What is important is the known declared bounds which get translated to erased bytecode for the supertype class.


A possible solution could use marker interfaces.

interface TransformT {}
interface TransformS {}
interface Transformable extends TransformT, TransformS {}

interface Transformer<T extends TransformT, S extends TransformS>
    T transform(S s);
    S transform(T t);
}

abstract class AbstractDTO implements Transformable {}
abstract class AbstractDomain implements Transformable {}

new SomeTransformerImpl<AbstractDTO, AbstractDomain>()

But I don't necessarily recommend doing this. It seems elaborate to me, although interesting. It depends on how complicated the actual class hierarchy is.

What Louis suggested in the comments is much simpler: give the methods different names.

like image 138
Radiodef Avatar answered Oct 24 '22 16:10

Radiodef