protected void listVirtualMethods(Class<?> type, List<VirtMeth> out) { if (!CPPObject.class.isAssignableFrom(type)) { return; } Class<?> sup = type.getSuperclass(); if (sup != CPPObject.class) { listVirtualMethods(sup, out); } int nParentMethods = out.size(); Map<Integer, VirtMeth> newVirtuals = new TreeMap<Integer, VirtMeth>(); methods: for (Method method : type.getDeclaredMethods()) { String methodName = method.getName(); Type[] methodParameterTypes = method.getGenericParameterTypes(); for (int iParentMethod = 0; iParentMethod < nParentMethods; iParentMethod++) { VirtMeth pvm = out.get(iParentMethod); Method parentMethod = pvm.definition; if (parentMethod.getDeclaringClass() == type) continue; // was just added in the same listVirtualMethods call ! // if (parentMethod.getAnnotation(Virtual.class) == null) // continue; // not a virtual method, too bad if (parentMethod.getName().equals(methodName) && isOverridenSignature( parentMethod.getGenericParameterTypes(), methodParameterTypes, 0)) { VirtMeth vm = new VirtMeth(); vm.definition = pvm.definition; vm.implementation = method; out.set(iParentMethod, vm); continue methods; } } Virtual virtual = method.getAnnotation(Virtual.class); if (virtual != null) { VirtMeth vm = new VirtMeth(); vm.definition = vm.implementation = method; newVirtuals.put(virtual.value(), vm); } } out.addAll(newVirtuals.values()); }