[ 
https://issues.apache.org/jira/browse/LANG-1323?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15979077#comment-15979077
 ] 

Sebb commented on LANG-1323:
----------------------------

Are you saying that some of the TypeUtils classes have incompatible equals() 
and hashCode() implementations?

If so, then that is clearly a bug. A test case would be useful.

However it is OK to provide a hashCode() implementation that is different from 
the 'standard' implementation, so long as it is consistent with the equals() 
defintion.

For example, if the hashCode() implementation always returns 42.
It's a terrible hash, but it does not break the hash/equals contract.
There is no requirement for unequal objects to have different hashes.

Indeed any class that assumes that equal hashCodes mean equal Objects is broken.
Object.hashCode() can produce equal hashCodes for unequal objects.

> Type implementations in TypeUtils compute hash code that breaks 
> Object.equals() with Sun's OpenJDK
> --------------------------------------------------------------------------------------------------
>
>                 Key: LANG-1323
>                 URL: https://issues.apache.org/jira/browse/LANG-1323
>             Project: Commons Lang
>          Issue Type: Bug
>          Components: lang.reflect.*
>    Affects Versions: 3.2, 3.5
>         Environment: Sun OpenJDK
>            Reporter: Scott Kilpatrick
>            Priority: Minor
>
> {{TypeUtils}} in {{lang.reflect}} provides convenient methods for creating 
> objects of the interface {{Type}}. Those objects are defined by the following 
> classes:
> * ParameterizedTypeImpl (implements {{ParameterizedType}})
> * WildcardTypeImpl (implements {{WildcardType}})
> * GenericArrayTypeImpl (implements {{GenericArrayType}})
> Similarly, there are corresponding classes, which implement the same 
> interfaces, defined in one's particular JDK. And it's these latter classes 
> that are instantiated when you get objects of type {{Type}} via reflection. 
> Let's call these the "internal {{Type}} implementations." In the case of 
> Sun's OpenJDK, [they are 
> defined|http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/sun/reflect/generics/reflectiveObjects]
>  in package {{sun.reflect.generics.reflectiveObjects}}.
> Each of the {{TypeUtils}} classes implements {{Object.equals(Object)}} in a 
> general way that's compatible with the internal {{Type}} implementations. For 
> example, if I access a field declared with type {{Map<String, Integer>}} and 
> get its generic type, via {{Field.getGenericType()}}, then that will be equal 
> to the {{TypeUtils}} object returned by:
> {code:java}
> TypeUtils.parameterize(Map.class, String.class, Integer.class)
> {code}
> That's what I'd expect, so that's great.
> However, the {{TypeUtils}} classes implement their {{Object.hashCode()}} 
> method in a _different_ way from the corresponding implementations in Sun 
> OpenJDK implementations. That's not so surprising, _but it breaks the 
> contract of {{Object.hashCode()}}_:
> bq. If two objects are equal according to the {{equals(Object)}} method, then 
> calling the {{hashCode}} method on each of the two objects must produce the 
> same integer result.
> In other words, the two {{Type}} objects above will both consider themselves 
> {{equals}} to each other, but they have different hash codes.
> One example of a negative consequence of this problem is a collection class 
> that implements its equality (to other collections) by checking hash codes of 
> its elements, e.g., Guava's immutable collections. If you have {{Type}} 
> objects in those collections, with {{TypeUtils}} {{Type}} objects in {{c1}} 
> and Sun OpenJDK {{Type}} objects in {{c2}}, you will see that 
> {{c1.equals(c2)}} returns {{false}} -- because their elements don't all have 
> the same hash codes -- even though those elements are all considered equal.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to