8224012: AnnotatedType implementations of hashCode() lead to StackOverflowError

Reviewed-by: jfranck
This commit is contained in:
Joe Darcy 2019-05-29 09:53:28 -07:00
parent 951e0b22d7
commit bc10b6aaff
2 changed files with 27 additions and 15 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -393,29 +393,22 @@ public final class AnnotatedTypeFactory {
return (TypeVariable)getType(); return (TypeVariable)getType();
} }
// For toString, the declaration of a type variable should // The declaration of a type variable should
// including information about its bounds, etc. However, the // include information about its bounds, etc. However, the
// use of a type variable should not. For that reason, it is // use of a type variable should not. For that reason, it is
// acceptable for the toString implementation of // acceptable for the toString and hashCode implementations of
// AnnotatedTypeVariableImpl to use the inherited // AnnotatedTypeVariableImpl to use the inherited
// implementation from AnnotatedTypeBaseImpl. // implementations from AnnotatedTypeBaseImpl.
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof AnnotatedTypeVariable) { if (o instanceof AnnotatedTypeVariable) {
AnnotatedTypeVariable that = (AnnotatedTypeVariable) o; AnnotatedTypeVariable that = (AnnotatedTypeVariable) o;
return equalsTypeAndAnnotations(that) && return equalsTypeAndAnnotations(that);
Arrays.equals(getAnnotatedBounds(), that.getAnnotatedBounds());
} else { } else {
return false; return false;
} }
} }
@Override
public int hashCode() {
return baseHashCode() ^
Objects.hash((Object[])getAnnotatedBounds());
}
} }
private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8058202 8212081 * @bug 8058202 8212081 8224012
* @summary Test java.lang.Object methods on AnnotatedType objects. * @summary Test java.lang.Object methods on AnnotatedType objects.
*/ */
@ -73,6 +73,8 @@ public class TestObjectMethods {
testWildcards(); testWildcards();
testFbounds();
if (errors > 0) { if (errors > 0) {
throw new RuntimeException(errors + " errors"); throw new RuntimeException(errors + " errors");
} }
@ -314,6 +316,23 @@ public class TestObjectMethods {
} }
} }
static void testFbounds() {
// Make sure equals and hashCode work fine for a type
// involving an F-bound, in particular Comparable<E> in
// java.lang.Enum:
//
// class Enum<E extends Enum<E>>
// implements Constable, Comparable<E>, Serializable
AnnotatedType[] types = Enum.class.getAnnotatedInterfaces();
for (int i = 0; i < types.length; i ++) {
for (int j = 0; j < types.length; j ++) {
checkTypesForEquality(types[i], types[j], i == j);
}
}
}
// The TypeHost and AnnotatedTypeHost classes declare methods with // The TypeHost and AnnotatedTypeHost classes declare methods with
// the same name and signatures but with the AnnotatedTypeHost // the same name and signatures but with the AnnotatedTypeHost
// methods having annotations on their return type, where // methods having annotations on their return type, where