Forcing two parameters of a generic method to have the same concrete type

醉酒当歌 提交于 2019-12-07 02:42:45

问题


How can I have a method with two parameters, with both parameters having the same concrete type?

For example,

boolean equals(Object a, Object b)

allows for a of any type and b of any type.

I want to force such that a and b have the same concrete type. I tried

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

and inputting a Date and a String to that method, expecting a compile-time error, but I get no errors, since T will resolve to ? extends Serializable & Comparable, since both Date and String implements Serializable and Comparable.


回答1:


You can't, basically. There's no way of doing that. Even if you could do it for a simple call to prohibit arguments of different types, it could always be bypassed using a cast:

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

If you're interested in the execution-time types of the arguments, you can only test that at execution time. There's no way of the compiler knowing whether an argument of type Date has a value which is a reference to precisely a java.util.Date or some subclass.




回答2:


The thing is your method's signature becomes

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

which doesn't give you any options. Even if you call

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

the compiler doesn't even need to break a sweat and determine the lowest common ancestor for your parameter types.

Edit

Interesting fact. I knew what I wrote above was true, but it still looked a bit weird. So I tested

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

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

Which the compiler yelled at. The reason is that the compiler indeed doesn't make a difference and just rewrites both methods as

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

which after type erasure becomes

boolean equals(Object a, Object b)

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

Long story short, your method equals(T,T) is the same as equals(Object, Object) due to type erasure and thus you can't force the same parameter type, at least at compile time, unless you specifically implement equals methods for each.



来源:https://stackoverflow.com/questions/25867191/forcing-two-parameters-of-a-generic-method-to-have-the-same-concrete-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!