28
28
import java .lang .reflect .WildcardType ;
29
29
import java .util .Arrays ;
30
30
import java .util .Collection ;
31
+ import java .util .HashSet ;
31
32
import java .util .IdentityHashMap ;
32
33
import java .util .Map ;
34
+ import java .util .Set ;
33
35
import java .util .StringJoiner ;
34
36
35
37
import org .springframework .core .SerializableTypeWrapper .FieldTypeProvider ;
@@ -588,18 +590,28 @@ public boolean hasUnresolvableGenerics() {
588
590
if (this == NONE ) {
589
591
return false ;
590
592
}
593
+ return hasUnresolvableGenerics (null );
594
+ }
595
+
596
+ private boolean hasUnresolvableGenerics (@ Nullable Set <Type > alreadySeen ) {
591
597
Boolean unresolvableGenerics = this .unresolvableGenerics ;
592
598
if (unresolvableGenerics == null ) {
593
- unresolvableGenerics = determineUnresolvableGenerics ();
599
+ unresolvableGenerics = determineUnresolvableGenerics (alreadySeen );
594
600
this .unresolvableGenerics = unresolvableGenerics ;
595
601
}
596
602
return unresolvableGenerics ;
597
603
}
598
604
599
- private boolean determineUnresolvableGenerics () {
605
+ private boolean determineUnresolvableGenerics (@ Nullable Set <Type > alreadySeen ) {
606
+ if (alreadySeen != null && alreadySeen .contains (this .type )) {
607
+ // Self-referencing generic -> not unresolvable
608
+ return false ;
609
+ }
610
+
600
611
ResolvableType [] generics = getGenerics ();
601
612
for (ResolvableType generic : generics ) {
602
- if (generic .isUnresolvableTypeVariable () || generic .isWildcardWithoutBounds () || generic .hasUnresolvableGenerics ()) {
613
+ if (generic .isUnresolvableTypeVariable () || generic .isWildcardWithoutBounds () ||
614
+ generic .hasUnresolvableGenerics (currentTypeSeen (alreadySeen ))) {
603
615
return true ;
604
616
}
605
617
}
@@ -619,12 +631,20 @@ private boolean determineUnresolvableGenerics() {
619
631
}
620
632
Class <?> superclass = resolved .getSuperclass ();
621
633
if (superclass != null && superclass != Object .class ) {
622
- return getSuperType ().hasUnresolvableGenerics ();
634
+ return getSuperType ().hasUnresolvableGenerics (currentTypeSeen ( alreadySeen ) );
623
635
}
624
636
}
625
637
return false ;
626
638
}
627
639
640
+ private Set <Type > currentTypeSeen (@ Nullable Set <Type > alreadySeen ) {
641
+ if (alreadySeen == null ) {
642
+ alreadySeen = new HashSet <>(4 );
643
+ }
644
+ alreadySeen .add (this .type );
645
+ return alreadySeen ;
646
+ }
647
+
628
648
/**
629
649
* Determine whether the underlying type is a type variable that
630
650
* cannot be resolved through the associated variable resolver.
0 commit comments