class Z {} class TParam {} class Zout {} class Zin {} class Params(val methodIndex: Int, val paramClass: Class<*>, val expectedReturnType: String, val expecedParamType: String) class Test() { fun test1(p: T): T? = null fun test2(p: Z): Z? = null fun test3(p: Z): Z? = null fun test4(p: X): Zout? = null fun test5(p: Y): Zin? = null } fun box(): String { val clz = javaClass>() val params = listOf( Params(1, javaClass(), "T", "T"), Params(2, javaClass>(), "Z", "Z"), Params(3, javaClass>(), "Z", "Z"), Params(4, javaClass(), "Zout", "X"), Params(5, javaClass(), "Zin", "Y") ) var result: String = "" for(p in params) { val fail = test(clz, p.methodIndex, p.paramClass, p.expectedReturnType, p.expecedParamType) if (fail != "OK") { result += fail + "\n"; } } return if (result.isEmpty()) "OK" else result; } fun test(clazz: Class<*>, methodIndex: Int, paramClass: Class<*>, expectedReturn : String, expectedParam : String): String { val method = clazz.getDeclaredMethod("test$methodIndex", paramClass)!!; if (method.getGenericReturnType().toString() != expectedReturn) return "fail$methodIndex: " + method.getGenericReturnType(); val test1Param = method.getGenericParameterTypes()!![0]; if (test1Param.toString() != expectedParam) return "fail${methodIndex}_param: " + test1Param; return "OK" }