1. 分析方法四要素  59

         * 第一要素:调用哪个对象

         * 第二要素:调用哪个方法

         * 第三要素:调用方法的时候传什么参数

         * 第四要素:方法执行结束之后的返回结果


         * 调用哪个对象的哪个方法,传什么参数,返回什么值。


         * 即使是使用反射机制调用方法,也同样需要具备这四个要素。

我们先来看一下,不使用反射机制调用一个方法需要几个要素的参与。

有一个这样的类:

package com.powernode.reflect;

/**
 * 回顾反射机制  59
 **/
public class SomeService {

    public void doSome(){
        System.out.println("public void doSome()执行。");
    }

    public String doSome(String s){
        System.out.println("public String doSome(String s)执行。");
        return s;
    }

    public String doSome(String s, int i){
        System.out.println("public String doSome(String s, int i)执行。");
        return s + i;
    }

}
package com.powernode.reflect;

//回顾反射机制  59
public class Test {
    public static void main(String[] args) {
        // 不使用反射机制调用这些方法
        SomeService someService = new SomeService();

        someService.doSome();

        /**
         * 分析:调用一个方法,当中含有几个要素?四要素。
         * 第一要素:调用哪个对象
         * 第二要素:调用哪个方法
         * 第三要素:调用方法的时候传什么参数
         * 第四要素:方法执行结束之后的返回结果
         *
         * 调用哪个对象的哪个方法,传什么参数,返回什么值。
         *
         * 即使是使用反射机制调用方法,也同样需要具备这四个要素。
         */
        String s1 = someService.doSome("张三");
        System.out.println(s1);

        String s2 = someService.doSome("李四", 250);
        System.out.println(s2);
    }
}

回顾反射机制_调用方法

2. 反射步骤 60

2.1 获取Method

要获取方法Method,首先你需要获取这个类Class

Class<?> clazz=Class.forName("com.powernode.reflect.SomeService");

当拿到Class之后,调用getDeclaredMethod()方法可以获取到方法。

假如你要获取这个方法:doSome(String s, int i)

Method doSomeMethod = clazz.getDeclaredMethod("doSome", String.class, int.class);

获取一个方法,需要告诉Java程序,你要获取的方法的名字是什么,这个方法上每个形参的类型是什么。这样Java程序才能给你拿到对应的方法。

这样的设计也非常合理,因为在同一个类当中,方法是支持重载的,也就是说方法名可以一样,但参数列表一定是不一样的,所以获取一个方法需要提供方法名以及每个形参的类型。

2.2  调用Method  60

要让一个方法调用的话,就关联到四要素了:

● 调用哪个对象的

● 哪个方法

● 传什么参数

● 返回什么值

第一步:创建对象(四要素之首:调用哪个对象的)

 Class<?> clazz = Class.forName("com.powernode.reflect.SomeService");
Object obj = clazz.newInstance();

第二步:获取方法

Method doSomeMethod = clazz.getDeclaredMethod("doSome", String.class, int.class);

第三步:调用方法

Object retValue = doSomeMethod.invoke(obj, "李四", 250);

四要素:调用哪个对象、哪个方法、传什么参数、返回什么值。

obj 要素:哪个对象

doSomeMethod 要素:哪个方法

"李四", 250 要素:传什么参数

retValue 要素:返回什么值。

2.3 演示调用doSome(String s, int i)

package com.powernode.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

//使用反射机制调用方法  60
public class Test2 {
    public static void main(String[] args) throws Exception{
        // 使用反射机制怎么调用方法。
        // 获取类
        Class<?> clazz = Class.forName("com.powernode.reflect.SomeService");

        // 获取方法
        Method doSomeMethod = clazz.getDeclaredMethod("doSome", String.class, int.class);

        // 调用方法
        // 四要素:调用哪个对象、哪个方法、传什么参数、返回什么值。
        // obj 要素:哪个对象
        // doSomeMethod 要素:哪个方法
        // "李四", 250 要素:传什么参数
        // retValue 要素:返回什么值。

        //因为我们的clazz.newInstance()方法已经过时了,
        // 还可以采用先获调用无参数构造方法然后在调用newInstance()方法
//        Constructor<?> con = clazz.getDeclaredConstructor();
//        Object o = con.newInstance();
        //过时了没关系,不影响使用
        Object obj = clazz.newInstance();
        Object retValue = doSomeMethod.invoke(obj, "李四", 250);
        System.out.println(retValue);
    }
}

回顾反射机制_User_02

2.4 演示调用doSome()

package com.powernode.reflect;

import java.lang.reflect.Method;

/**
 * 使用反射机制调用方法  60
 **/
public class Test3 {
    public static void main(String[] args) throws Exception{
        // 获取类
        Class<?> clazz = Class.forName("com.powernode.reflect.SomeService");
        // 获取方法
        Method doSomeMethod = clazz.getDeclaredMethod("doSome");
        // 调用方法
        //创建对象
        Object obj = clazz.newInstance();
        doSomeMethod.invoke(obj);
    }
}

回顾反射机制_反射机制_03

3. SpringDI的核心实现  61

3.1 需求: 61

            假设你现在已知以下信息:

                1. 有这样一个类,类名叫做:com.powernode.reflect.User

                2. 这个类符合javabean规范。属性私有化,对外提供公开的setter和getter方法。

                3. 你还知道这个类当中有一个属性,属性的名字叫做 age

                4. 并且你还知道age属性的类型是int类型。

            请使用反射机制调用set方法,给User对象的age属性赋值。

package com.powernode.reflect;

/**
 * SpringDI的核心实现  61
 **/
public class User {
    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.powernode.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * SpringDI的核心实现  61
 **/
public class Test4 {
    public static void main(String[] args) throws Exception {
        /*
        需求:
            假设你现在已知以下信息:
                1. 有这样一个类,类名叫做:com.powernode.reflect.User
                2. 这个类符合javabean规范。属性私有化,对外提供公开的setter和getter方法。
                3. 你还知道这个类当中有一个属性,属性的名字叫做 age
                4. 并且你还知道age属性的类型是int类型。
            请使用反射机制调用set方法,给User对象的age属性赋值。
         */
        String className = "com.powernode.reflect.User";
        String propertyName = "age";

        // 通过反射机制调用setAge(int)方法
        // 获取类
        Class<?> clazz = Class.forName(className);

        // 获取方法名
        String setMethodName = "set" + propertyName.toUpperCase().charAt(0) + propertyName.substring(1);

        // 根据属性名获取属性类型
        Field field = clazz.getDeclaredField(propertyName);

        // 获取方法
        Method setMethod = clazz.getDeclaredMethod(setMethodName, field.getType());

        // 准备对象
        Object obj = clazz.newInstance();

        // 调用方法
        setMethod.invoke(obj, 30);

        System.out.println(obj);

    }
}

回顾反射机制_反射机制_04