--- old/src/java.desktop/share/classes/java/awt/image/ColorModel.java 2016-07-20 22:17:15.844921472 +0530 +++ new/src/java.desktop/share/classes/java/awt/image/ColorModel.java 2016-07-20 22:17:15.640921472 +0530 @@ -31,10 +31,11 @@ import sun.java2d.cmm.CMSManager; import sun.java2d.cmm.ColorTransform; import sun.java2d.cmm.PCMM; -import java.awt.Toolkit; +import java.util.Arrays; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; +import java.util.Objects; /** * The {@code ColorModel} abstract class encapsulates the @@ -170,6 +171,7 @@ int colorSpaceType = ColorSpace.TYPE_RGB; int maxBits; boolean is_sRGB = true; + private volatile int hashCode; /** * Data type of the array used to represent pixel values. @@ -362,7 +364,14 @@ this.transparency = transparency; } - nBits = bits.clone(); + /* + * We need significant bits value only for the length + * of number of components, so we truncate remaining part. + * It also helps in hashCode calculation since bits[] can contain + * different values after the length of number of components between + * two ColorModels. + */ + nBits = Arrays.copyOf(bits, numComponents); this.pixel_bits = pixel_bits; if (pixel_bits <= 0) { throw new IllegalArgumentException("Number of pixel bits must "+ @@ -1441,28 +1450,65 @@ } /** - * Tests if the specified {@code Object} is an instance of - * {@code ColorModel} and if it equals this + * Tests if the specified {@code Object} equals this * {@code ColorModel}. + * In order to protect the symmetry property of + * {@code (a.equals(b) == b.equals(a))}, + * the target object must be the same class (and not a subclass) + * as this object to evaluate as {@code equals}. + *

+ * Subclasses may check additional properties, but this method + * will check the following basic properties for equivalence to + * determine if the target object equals this object: + * + *

+ *

+ * Subclasses should override this method if they have any additional + * properties to compare and should use the following implementation. + * Note that the base {@code ColorModel} class already ensures that + * the target object is the same class as this object so the cast to + * the subclass type can be assumed if {@code super.equals(obj)} returns + * true. + *

+     *     public boolean equals(Object obj) {
+     *         if (!super.equals(obj)) {
+     *             return false;
+     *         }
+     *         MyCMClass cm = (MyCMClass) obj;
+     *         // test additional properties on "cm" and "this"
+     *     }
+     * 
+ *

* @param obj the {@code Object} to test for equality * @return {@code true} if the specified {@code Object} - * is an instance of {@code ColorModel} and equals this - * {@code ColorModel}; {@code false} otherwise. + * equals this {@code ColorModel}; {@code false} otherwise. */ + @Override public boolean equals(Object obj) { - if (!(obj instanceof ColorModel)) { + if (this == obj) { + return true; + } + if ((obj == null) || (obj.getClass() != getClass())) { return false; } - ColorModel cm = (ColorModel) obj; - if (this == cm) { - return true; - } + ColorModel cm = (ColorModel) obj; if (supportsAlpha != cm.hasAlpha() || isAlphaPremultiplied != cm.isAlphaPremultiplied() || pixel_bits != cm.getPixelSize() || transparency != cm.getTransparency() || - numComponents != cm.getNumComponents()) + numComponents != cm.getNumComponents() || + (!(colorSpace.equals(cm.colorSpace))) || + transferType != cm.transferType) { return false; } @@ -1487,22 +1533,21 @@ * * @return a hash code for this ColorModel. */ + @Override public int hashCode() { - - int result = 0; - - result = (supportsAlpha ? 2 : 3) + - (isAlphaPremultiplied ? 4 : 5) + - pixel_bits * 6 + - transparency * 7 + - numComponents * 8; - - if (nBits != null) { - for (int i = 0; i < numComponents; i++) { - result = result + nBits[i] * (i + 9); - } + int result = hashCode; + if (result == 0) { + result = 7; + result = 89 * result + this.pixel_bits; + result = 89 * result + Arrays.hashCode(this.nBits); + result = 89 * result + this.transparency; + result = 89 * result + (this.supportsAlpha ? 1 : 0); + result = 89 * result + (this.isAlphaPremultiplied ? 1 : 0); + result = 89 * result + this.numComponents; + result = 89 * result + Objects.hashCode(this.colorSpace); + result = 89 * result + this.transferType; + hashCode = result; } - return result; }