getModifiers()
先看jdk中的方法说明java.lang.reflect.Method:
@Override
public int getModifiers() {
return modifiers;
}
我们看到有一个@Override注解
我们其看父类:java.lang.reflect.Executable
/**
* Returns the Java language {@linkplain Modifier modifiers} for
* the executable represented by this object.
*/
public abstract int getModifiers();
从注释可以看出,这个方法返回的是int类型的方法上的修复符号
看一个测试
public class Modle {
String a;
private String b;
protected String c;
public String d;
final String e="";
static String f;
public static String g;
public static final String h="";
String geta(){return "";}
private void getb(){}
protected void getc() {}
static void getd() {}
public static final void gete(){}
}
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestMethod {
@Test
public void test() {
Class clazz = Modle.class;
for (Field f : clazz.getDeclaredFields()) {
System.out.println("field:" + f.getName() + ":" + f.getModifiers());
}
for (Method m : clazz.getDeclaredMethods()) {
System.out.println("method:" + m.getName() + ":" + m.getModifiers());
}
}
}
field:a:0
field:b:2
field:c:4
field:d:1
field:e:16
field:f:8
field:g:9
field:h:25
method:getb:2
method:getc:4
method:geta:0
method:getd:8
method:gete:25
送上面的结果可以看到,不适用任何修饰符, getModifiers()返回0
public:1
private:2
protect: 4
static:8
final:16
public + static + final = 1 + 8 + 16 = 15
isBridge()
先看jdk中的方法说明java.lang.reflect.Method:
/**
* Returns {@code true} if this method is a bridge
* method; returns {@code false} otherwise.
*
* @return true if and only if this method is a bridge
* method as defined by the Java Language Specification.
* @since 1.5
*/
public boolean isBridge() {
return (getModifiers() & Modifier.BRIDGE) != 0;
}
上面注解说道brigeMethod(桥接方法), 啥是桥接方法:
原来jdk5引入了泛型,但是泛型在编译后又是没有的,即泛型擦除。
这样在编译的时候,就引入了桥接方法,举个栗子:
public class Parent {
public void process(T t){
System.out.println("parent:"+t);
}
public void print(Object obj){
System.out.println("parent:"+obj);
}
}
public class Son extends Parent {
public void process(String str) {
System.out.println("son:"+str);
}
public void print(String obj){
System.out.println("son:"+obj);
}
public static void main(String[] args) {
Parent son = new Son();
son.process("son");
son.print("son");
for(Method method : Son.class.getDeclaredMethods()) {
System.out.println(method.getName()+"("+method.getParameterTypes()[0]+"), isBridge:" +method.isBridge());
}
}
}
执行结果:
son:son
parent:son
main(class [Ljava.lang.String;), isBridge:false
print(class java.lang.String), isBridge:false
process(class java.lang.String), isBridge:false
process(class java.lang.Object), isBridge:true
第一个执行了子类的方法,第二个执行了父类的方法。
按道理说泛型类型擦除了,父类的两个方法中的参数类型应该都是Object
我们看看Son的字节码
$ javap -c Son.class
Compiled from "Son.java"
public class Son extends Parent {
public Son();
Code:
0: aload_0
1: invokespecial #1 // Method Parent."":()V
4: return
public void process(java.lang.String);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."":()V
10: ldc #5 // String son:
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: return
public void print(java.lang.String);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."":()V
10: ldc #5 // String son:
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: return
public static void main(java.lang.String[]);
Code:
0: new #9 // class Son
3: dup
4: invokespecial #10 // Method "":()V
7: astore_1
8: aload_1
9: ldc #11 // String son
11: invokevirtual #12 // Method Parent.process:(Ljava/lang/Object;)V
14: aload_1
15: ldc #11 // String son
17: invokevirtual #13 // Method Parent.print:(Ljava/lang/Object;)V
20: return
public void process(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: checkcast #14 // class java/lang/String
5: invokevirtual #15 // Method process:(Ljava/lang/String;)V
8: return
}
从上面字节码来看, 最后一个接收Object类型的process方法,在第5步调用了接收String类型的process方法。这个接收Object类型参数的process就是bridge方法。
在子类中没有接收Object类型的print方法,因为子类复写了父类的print方法。
isVarArgs() 是否可变参数
总结:
我们在工作中,使用到,或者了解到的java只是其冰山一角,下次看谁再说精通java。