Why doesn't javax MimeType implement peers?

the javax.activation.MimeType class is not compared intuitively (to me) due to the lack of an overridden equals method. Consider the following fragment:

 MimeType a = new MimeType("image/png"); MimeType b = new MimeType("image/png"); a.equals(b); // false a.toString().equals(b.toString()); // true a.getBaseType().equals(b.getBaseType());// true a.getSubType().equals(b.getSubType()); // true a.getParameters().size(); // 0 b.getParameters().size(); // 0 

It seems to me that a and b are equal in all aspects and that a.equals(b) should return true .

Is there a reason this class does not implement the equals method?

Update: there is a match - a method that does exactly what I want, but I found out only after posting this question, which the view confirms is not so intuitive of this class.

+5
source share
2 answers

I can only assume that this solution is not documented, but when checking the MimeType class MimeType there are two matching methods: match(MimeType) and match(String) . The second performs this task by creating a MimeType object from the string argument and then calling the first match method.

Thus, by implementing matching methods, you can compare with MimeType and String objects. This would not be possible by implementing the equals(Object) method. Of course, you could implement the equals method so that it can be compared with both MimeType and String , but that would break the contract specified in the equals documentation:

It is symmetrical: for any non-empty reference values ​​x and y x.equals (y) should return true if and only if y.equals (x) returns true.

This will only work if String.equals(Object o) uses o.toString() for comparison, but the String doc states:

Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.

This way you can use equals only for comparison with another MimeType , and if you want to compare with String , you will have to return to the match(String) method.

And I think the reason not to implement equals in this class is just to support the method that you use for comparison, consistent across different objects for comparison.

0
source

You may consider the bug; at first glance, it looks like a class that should correctly override .equals() and .hashCode() . Of course, this will not help you for some time (not sure if this library is in the JDK release cycle).

As a workaround, you can create a subclass or wrapper class that properly implements .equals() and .hashCode() , for example:

 public class ValueMimeType extends MimeType { // constructors @Override public boolean equals(Object o) { if (this == o) return true; if (o instanceof ValueMimeType) { // not MimeType, as that wouldn't be symetric return match((ValueMimeType) o); } return false; } @Override public int hashCode() { return toString().hashCode(); } } 

And always use ValueMimeType instead of MimeType . Obviously not perfect, but better than nothing.

0
source

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


All Articles