java8的很多特性是java虚拟机层面实现的,比如lamda表达式是由新版本的JVM支持的,而不是编译器是实现。
但是default修饰符,其实更准确的定义是“在接口定义的,非抽象的,public的修饰符”,在编译为字节码后应该没有该标识符。
我们看下API来验证下: Modifier.toString(int mod)输出不了defalut修饰符, 而实际上也没有定义defalut修饰符。
String java.lang.reflect.Modifier.toString(int mod) public static String toString(int mod) { StringBuilder sb = new StringBuilder(); int len; if ((mod & PUBLIC) != 0) sb.append("public "); if ((mod & PROTECTED) != 0) sb.append("protected "); if ((mod & PRIVATE) != 0) sb.append("private "); /* Canonical order */ if ((mod & ABSTRACT) != 0) sb.append("abstract "); if ((mod & STATIC) != 0) sb.append("static "); if ((mod & FINAL) != 0) sb.append("final "); if ((mod & TRANSIENT) != 0) sb.append("transient "); if ((mod & VOLATILE) != 0) sb.append("volatile "); if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized "); if ((mod & NATIVE) != 0) sb.append("native "); if ((mod & STRICT) != 0) sb.append("strictfp "); if ((mod & INTERFACE) != 0) sb.append("interface "); if ((len = sb.length()) > 0) /* trim trailing space */ return sb.toString().substring(0, len-1); return ""; }我们从java.lang.reflect.Method.isDefault()入手:
/**@since 1.8 */ public boolean isDefault() { // Default methods are public non-abstract instance methods // declared in an interface. return ((getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) == Modifier.PUBLIC) && getDeclaringClass().isInterface(); }所以我们可以这么写输入任何一个类的方法的代码:
public static String getMethodSimpleInfo(Class<?> clazz) { StringBuilder sb = new StringBuilder(); Arrays.stream(clazz.getMethods()).forEach((m)->{ String pStr = Arrays.stream(m.getParameterTypes()).map(Class::getSimpleName).collect(Collectors.joining(",")); sb.append(m.isDefault()?"default":Modifier.toString(m.getModifiers())).append(" ") .append(m.getReturnType().getSimpleName()).append(" ") .append(m.getName()+" ") .append("(") .append(pStr) .append(");") .append(m.getDeclaringClass().getSimpleName()); }); return sb.toString(); } public static String getMethodSimpleGenericInfo(Class<?> clazz) { return clazz.toGenericString().replaceAll("([a-zA-Z]+\\.)", ""); }