Java反射(Method)(三)

简介: 日常开发中,我们可使用反射获取JavaBean的方法信息,而描述属性信息的就是Java Method,Method类同样位于java.lang.reflect包下。

前言

image (1).png
日常开发中,我们可使用反射获取JavaBean的方法信息,而描述属性信息的就是Java Method,Method类同样位于java.lang.reflect包下。

Method

Method提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法),如果你想要通过反射调用类的私有方法时,要先在这个私有方法对应的Method对象上调用setAccessible来取消对这个方法的访问检查,再调用invoke方法来执行这个私有方法。

/**
* A {@code Method} provides information about, and access to, a single method
* on a class or interface.  The reflected method may be a class method
* or an instance method (including an abstract method).
*
* <p>A {@code Method} permits widening conversions to occur when matching the
* actual parameters to invoke with the underlying method's formal
* parameters, but it throws an {@code IllegalArgumentException} if a
* narrowing conversion would occur.
*
* @see Member
* @see java.lang.Class
* @see java.lang.Class#getMethods()
* @see java.lang.Class#getMethod(String, Class[])
* @see java.lang.Class#getDeclaredMethods()
* @see java.lang.Class#getDeclaredMethod(String, Class[])
*
* @author Kenneth Russell
* @author Nakul Saraiya
*/
public final class Method extends Executable {
    //.....
}

getModifiers

  • 以整数形式返回由此Method对象表示的字段的Java语言修饰符(例如private、final、static等)。
@Data
public class User {
    private String name;
    
    private int age;
    
    public void print(String name) {
        if (null == name) {
            return;
        }
        if (name.equals(this.name)) {
            System.out.println(this.age);
        }
    }
}

public static void main(String[] args) throws Exception {
    
    Method method = User.class.getMethod("print", String.class);

    // public
    System.out.println(Modifier.toString(method.getModifiers()));

}

getReturnType

  • 返回一个Class对象,该对象描述了此Method对象所表示的方法的正式返回类型。
    class User {

        private String name;

        private int age;

        public int getAge(String name) {
            if (null == name) {
                return 0;
            }
            if (name.equals(this.name)) {
                return this.age;
            }
            return 0;
        }
    }

    public static void main(String[] args) throws Exception {

        Method method = User.class.getMethod("getAge", String.class);
        // int
        System.out.println(method.getReturnType());

    }

getName

  • 以String形式返回此Method对象表示的方法名称。
class User {

        private String name;

        private int age;

        public int getAge(String name) {
            if (null == name) {
                return 0;
            }
            if (name.equals(this.name)) {
                return this.age;
            }
            return 0;
        }
    }

    public static void main(String[] args) throws Exception {

        Method method = User.class.getMethod("getAge", String.class);

        // getAge
        System.out.println(method.getName());
    }

getParameterTypes

  • 按照声明顺序返回Class对象的数组,这些对象描述了此Method对象所表示的方法的形参类型。如果底层方法不带参数,则返回长度为0的数组。
    public static void main(String[] args) throws Exception {

        Method method = User.class.getMethod("getAge", String.class);

        // java.lang.String
        Stream.of(method.getParameterTypes()).forEach(t-> System.out.println(t.getName()));
    }

    class User {

        private String name;

        private int age;

        public int getAge(String name) {
            if (null == name) {
                return 0;
            }
            if (name.equals(this.name)) {
                return this.age;
            }
            return 0;
        }
    }

getExceptionTypes

  • 返回Class对象的数组,这些对象描述了声明将此Method对象表示的底层方法抛出的异常类型。如果此方法没有在其throws子句中声明异常,则返回长度为0的数组。
 public static void main(String[] args) throws Exception {

        Method method = User.class.getMethod("getAge", String.class);

         // io.terminus.common.exception.ServiceException
        Stream.of(method.getExceptionTypes()).forEach(t-> System.out.println(t.getName()));
    }

    class User {

        private String name;

        private int age;

        public int getAge(String name) throws ServiceException {
            if (null == name) {
                return 0;
            }
            if (name.equals(this.name)) {
                return this.age;
            }
            return 0;
        }
    }

getDeclaringClass

  • 返回方法所在的类
    public static void main(String[] args) throws Exception {

        Method method = User.class.getMethod("getAge", String.class);

        // class cn.gov.zcy.item.Test$User
        System.out.println(method.getDeclaringClass());
    }

    class User {

        private String name;

        private int age;

        public int getAge(String name) throws ServiceException {
            if (null == name) {
                return 0;
            }
            if (name.equals(this.name)) {
                return this.age;
            }
            return 0;
        }
    }

invoke

  • 对带有指定参数的指定对象调用由此Method对象表示的底层方法。
  • 个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。
  • 如果底层方法是静态的,那么可以忽略指定的obj参数。该参数可以为null。
  • 如果底层方法所需的形参数为 0,则所提供的args数组长度可以为0或null。
  • 如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在Java Language Specification, Second Edition 的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。
  • 如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。
    public static void main(String[] args) throws Exception {

        User user = new User();

        Method setAgeMethod = user.getClass().getMethod("setAge", int.class);
        Method setNameMethod = user.getClass().getMethod("setName", String.class);
        setAgeMethod.invoke(user, 22);
        setNameMethod.invoke(user, "晓断");

        // User(name=晓断, age=22)
        System.out.println(user);

    }

    @ToString
    static
    class User {

        private String name;

        private int age;

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

        public void setName(String name) {
            this.name = name;
        }
    }
目录
相关文章
|
2月前
|
网络协议 算法 Java
|
2月前
|
Java 关系型数据库 MySQL
在Java的反射中,Class.forName和ClassLoader的区别
在Java的反射中,Class.forName和ClassLoader的区别
36 3
|
3天前
|
Java
【专栏】Java中的反射机制与应用实例
【4月更文挑战第27天】本文探讨了Java反射机制,该机制允许程序在运行时获取类信息、动态创建对象、调用方法和访问属性。反射通过Class、Constructor、Method和Field类实现。文中列举了反射的应用场景,如动态创建对象、调用方法、访问属性和处理注解,并提供了相关实例代码演示。
|
4天前
|
设计模式 Java Spring
来聊聊Java的反射机制(下)
来聊聊Java的反射机制(下)
7 0
|
6天前
|
Java
Java 反射
Java 反射
|
7天前
|
设计模式 Java 索引
由反射引出的Java动态代理与静态代理
由反射引出的Java动态代理与静态代理
12 0
|
7天前
|
存储 Java Shell
深入剖析Java中的反射,由浅入深,层层剥离!
深入剖析Java中的反射,由浅入深,层层剥离!
11 1
|
11天前
|
监控 Java 开发者
掌握 Java 反射和动态代理
【4月更文挑战第19天】Java反射和动态代理提供强大功能和灵活性。反射允许运行时检查和操作类,获取类信息、动态调用方法,但可能带来性能损失和降低代码可读性。动态代理则用于创建代理对象,实现透明性和横切关注点分离,常用于日志、权限检查等。两者结合能实现更复杂功能。掌握这些技术能提升代码的灵活性和可扩展性,但也需注意性能和可读性。通过学习和实践,能更好地构建高效软件系统。
|
18天前
|
Java
代码的魔法师:Java反射工厂模式详解
代码的魔法师:Java反射工厂模式详解
27 0
|
22天前
|
安全 Java
java反射篇
java反射篇