Forcing two parameters of a general method to the same specific type

How can I use a method with two parameters, with both parameters having the same specific type?

For instance,

boolean equals(Object a, Object b) 

admits a any type and b any type.

I want to make it so that a and b have the same specific type. I tried

 <T> boolean equals(T a, T b) 

and introducing Date and a String into this method, expecting a compile-time error, but I don't get errors, since T will solve ? extends Serializable & Comparable ? extends Serializable & Comparable , since both Date and String implement Serializable and Comparable .

+6
source share
2 answers

You cannot, in principle. There is no way to do this. Even if you can do this for a simple call that prohibits arguments of different types, you can always get around it with cast:

 equals((Object) date, (Object) string) 

If you are interested in the types of execution arguments, you can only check this at runtime. There is no way for the compiler to find out if an argument of type Date value that is a reference to exactly java.util.Date or some subclass.

+7
source

The fact is that your method signature becomes

 <? extends Object> boolean equals(? extends Object a, ? extends Object b) 

which does not give you any options. Even if you call

 equals(new Date(), "hello world"); 

the compiler does not even need to break the sweat and determine the lowest common ancestor for your parameter types.

Edit

Interesting fact. I knew that what I wrote above was true, but it still looked a little strange. So I tested

 <T> boolean equals(T a, T b) { return true; } <T,E> boolean equals(T a, E b) { return true; } 

Which compiler screamed. The reason is that the compiler really doesn't matter and just rewrites both methods as

 boolean equals(? extends Object a, ? extends Object b) 

which after erasing styles becomes

 boolean equals(Object a, Object b) 

which is the same signature. Indeed, if I save your equals(T,T) method and I add another method with the equals(Object, Object) signature, the compiler continues to say that I have the same method that was declared elsewhere.

In short , your equals(T,T) method matches equals(Object, Object) due to type erasure, and therefore you cannot force the same parameter type, at least at compile time, unless you specifically implement equals methods for everyone.

+1
source

Source: https://habr.com/ru/post/975349/


All Articles