Well ... you can do it yourself using antlr4 using the following grammar
type returns[ClassBuilder value] : cls=CLASS { $value = ClassBuilder.parse($cls.text); } | cls=CLASS { $value = ClassBuilder.parse($cls.text); } LT head=type { $value.add($head.value); } (COMMA tail=type { $value.add($tail.value); })* GT ; GT : '>' ; LT : '<' ; COMMA : ',' ; CLASS : ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9'|'$'|'.'|'_')* ;
Where ClassBuilder looks like
public class ClassBuilder { private final Class<?> clazz; private final List<ClassBuilder> parameters = new ArrayList<>(); public ClassBuilder(final Class<?> clazz) { this.clazz = clazz; } public static ClassBuilder parse(String clazz) { try { return new ClassBuilder(Class.forName(clazz)); } catch (ClassNotFoundException e) {
And then finally analyze the string
CharStream stream = new ANTLRInputStream( "java.util.Map<java.util.List<java.lang.Integer>, java.util.Set<java.lang.String>>" ); TokenStream tokenStream = new CommonTokenStream(new ParametrizedTypeLexer(stream)); ParametrizedTypeParser parser = new ParametrizedTypeParser(tokenStream); assertEquals( new TypeToken<Map<List<Integer>, Set<String>>>() {}.getType(), parser.type().value.build() );
You can see a working example here .
Note
CLASS The lexer rule may be a little inaccurate. In addition, this parser applies only to non-primitive classes and parameterized types, but you, of course, extend it to support wildcard types.
source share