我想通过java反射找到一个方法是否是一个"默认方法"java.lang.Iterable
.我试过打印方法.
代码片段:
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class ReflectionTest {
public static void main(String[] args) {
Class c = Iterable.class;
for(Method m : c.getDeclaredMethods())
{
System.out.print(Modifier.toString(m.getModifiers()));
System.out.println(" "+m.getName());
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
public abstract iterator
public spliterator
public forEach
Run Code Online (Sandbox Code Playgroud)
这里,spliterator()和forEach()应该打印出来default
.
如果我的解释错误,请纠正我.
在最近的java8更新版本中,我们isDefault()
在java.lang.reflect.Method
课堂上有这个技巧.
稍微修改我以前的代码会产生结果.
码:
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class ReflectionTest {
public static void main(String[] args) {
Class c = Iterable.class;
for(Method m : c.getDeclaredMethods())
{
System.out.print(Modifier.toString(m.getModifiers()));
System.out.println(" "+(m.isDefault()?"default ":"")+m.getName());
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
public abstract iterator
public default spliterator
public default forEach
Run Code Online (Sandbox Code Playgroud)
注意:我在jdk8 update 20中测试了这个
不要那样依赖Modifier.toString
.在过去,类,字段和方法的修饰符被赋予唯一的不同值,因此您可以解释它们,而无需查看拥有修饰符的实体的类型,就像该方法所暗示的那样.
但是随着Java的发展,增加了更多的修饰符位,并且无法保存该属性.特别是,当将方法的修饰符位传递给Modifier.toString
未修改时,您将获得以下令人惊讶的行为:
volatile
transient
因此,您应该过滤这些位.Java 7 引入了一种提供正确掩码的方法,以便您可以使用Modifier.toString(m.getModifiers()&Modifier.methodModifiers())
.
但这只能起作用,因为旧的Java关键字映射到唯一的修饰符位,而较新的修饰符位不与关键字相关联.对于较新的Java版本,即使这可能是不够的.
对于default
关键字,它甚至更简单:没有与关键字关联的修饰符位.如果public
,非abstract
,非static
法中出现一个interface
,它必须是一个default
方法.这就是Method.isDefault()
决定方法是否是方法的default
方法.Modifier.toString(…)
没有机会知道声明的类是否是一个interface
,因此永远不会打印default
.