java-classmate icon indicating copy to clipboard operation
java-classmate copied to clipboard

Correct approach to compare `ResolvedType` with a raw `Class<?>`?

Open garretwilson opened this issue 9 months ago • 3 comments

What's the appropriate way to see if a ResolvedType represents a simple class that I know about?

Let's say I pass a new GenericType<String>{} to a method, and I just want to see if the generic parameter is String. I think (I haven't tried it yet) I would do this (code not optimized, for illustration):

void foo(GenericType<?> genericType) {
  TypeResolver typeResolver = new TypeResolver();
  ResolvedType resolvedType = typeResolver.resolve(genericType);

How would I then see if resolvedType indicates a simple String? I'm guessing I could do this:

    if(resolvedType.getTypeParameters.isEmpty() && resolvedType.getErasedType().equals(String.class)) {
      …

But that seems sort of awkward. Is there a better way?

(Note that the resolvedType.getTypeParameters.isEmpty() check is arguably not necessary here, as String has no generic parameters, but I'm looking for a general approach.)

Or should I be going in the other direction, resolving String.class and then comparing the resolved types?

    if(resolvedType.equals(typeResolver.resolve(String.class))) {
      …

I don't know how much overhead the extra resolution of String.class adds, though.

This may be related to #31.

garretwilson avatar Oct 02 '23 14:10 garretwilson

What you include sounds like the way to do it, in general case (and yes, for special case of non-generic type, just checking "erased type" would be the thing to do).

I'd be open to adding convenience method if there's an obvious API addition to do (that is, generally useful method to add).

cowtowncoder avatar Oct 04 '23 03:10 cowtowncoder

Thanks for the reply. I'll continue with my project project and learn more about the best approach; and consider what convenience function would be useful.

Note that I updated the code in the question, because after running my code I realized that typeResolver.resolve(genericType) throws away the GenericType part and just gives me the type of <T>. So GenericType<T> really is just a carrier in ClassMate's view. (I had assumed the return type would give me information on GenericType itself, analogous to how typeResolver.resolve(someClass) seems to work in the documentation, but the way it actually works is better now that I understand it.)

garretwilson avatar Oct 04 '23 22:10 garretwilson

Ah. Yes. I should have read your sample more carefully. Yes, GenericType is a carrier that has to be used to retain actual generic type via sub-classing, generating new type for that purpose.

cowtowncoder avatar Oct 05 '23 02:10 cowtowncoder