4Java反射与泛型——1反射——3调用方法(廖雪峰)

1Method

通过class实例获取方法Method信息:

  • getMethod(name,Class...):获取某个public的method(包括父类)
  • getDeclaredMethod(name,Class...):获取当前类的某个method(不包括父类)
  • getMethods():获取所有public的method(包括父类)
  • getDeclaredMethods():获取当前类的所有method(不包括父类)
    Animal.java

2Method对象

Method对象包含一个method的所有信息:

  • getName():返回方法名称
  • getReturnType():返回方法的返回类型
  • getParameterTypes():返回方法的参数类型
  • getModifiers():返回方法的修饰符
Integer n = new Integer(123);
Class cls = n.getClass();
Method[] ms = cls.getMethods();
for (Method m : ms) {
    m.getName();//method name
    //return type:
    Class ret = m.getReturnType();
    //parameter types:
    Class[] params = m.getParameterTypes();
    m.getModifiers();//modifiers
}

调用带参数的Method:

  • 可以通过具体的参数类型来获取指定的方法,注意:如果根据给定的方法名称以及参数类型无法匹配到相应的方法,则会抛出NoSuchMethodException
  • Object invoke(Object obj,Object...args) (实例变量,方法参数)
Integer n = new Integer(123);
Class cls = n.getClass();
Method[] ms = cls.getMethods("compareTo",Integer.class);
int r = (Integer) m.invoke(n,456);
//-1,相当于int r = n.compareTo(456);

3实例演示

public class Main {
	
    public static void main(String[] args) throws Exception{
	Student s = new Student();
	Class cls = s.getClass();
	Method m = cls.getMethod("setAddress", String.class);
	//printMethodInfo(m);
	m.invoke(s, "shanghai");
	//可以利用JavaBean获取信息
	BeanInfo bi = Introspector.getBeanInfo(cls);
	for (PropertyDescriptor pb : bi.getPropertyDescriptors()) {
	    System.out.println(pb.getName());
	    printMethodInfo(pb.getReadMethod());
	    printMethodInfo(pb.getWriteMethod());
	}
	s.hello();
    }

    private static void printMethodInfo(Method m) {
		
	System.out.println(m);
	System.out.println("method name:" + m.getName());
	System.out.println("return type:" + m.getReturnType());
        System.out.println("parameters:"+
Arrays.toString(m.getParameters()));
	System.out.println("method modifiers:" + m.getModifiers());
    }
}
public class Student extends Person implements Hello{
    static int number = 0;
    public String name;
    private String address = "beijing";
    public Student() {
	this("unNamed");
    }
    public Student(String name) {
	this.name = name;
    }
    public void hello() {
	System.out.println("Hi, "+name+" from " +address +"!");
    }
    public String getAddress() {
	return address;
    }
    public void setAddress(String address) {
	this.address = address;
    }
}
public class Person {
    public int age;

    public int getAge() {
	return age;
    }

    public void setAge(int age) {
	this.age = age;
    }
}
public interface Hello {
    public void hello();
}

 4多态

从Person.class获取的Method,作用于Student实例时:

  • 实际调用方法是Student覆写的方法
  • 保证了多态的正确性
class Person {
    public void hello() {
        System.out.println("Person:hello");
    }
}

class Student extends Person {
    public void hello() {
        System.out.println("Student:hello");
    }
}

Method m = Person.class.getMethod("hello");
m.invoke(new Student());

5总结

  • Method对象封装了方法的所有信息
  • 通过Class实例的方法可以获取Method实例:getMethod/getMethods/getDeclaredMethod/getDeclaredMethods
  • 通过Method实例可以获取方法信息:getName/getReturnType/getParameterTypes/getModifiers
  • 通过Method实例可以调用某个对象的方法:Object invoke(Object instance,Object...parameters)
  • 通过设置setAccessible(true)来访问非public方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小夏天禧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值