java反射-Method中的invoke方法的用法-以及函数式接口和lambda表达式

作者最近研究框架底层代码过程中感觉自己基础不太牢固,于是写了一点案例,以防日后忘记

接口类:Animals

1 public interface Animals {
2
3     public void eat();
4 }
package cn.chenc.study.entity;

public interface InterfaceFactory {

    public String show(int i);

}

实体类:Person

package cn.chenc.study.entity;

import java.lang.reflect.Proxy;

public class Person implements Animals {
    private String name;
    private int age;

    public Person(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 "Person{" +
                "name=‘" + name + ‘\‘‘ +
                ", age=" + age +
                ‘}‘;
    }

    public void show(String name,int age){
        System.out.println("name="+name+",age="+age);
    }

    public void eat(){
        System.out.println("人用餐具吃饭");

    }

    public void run(String s,int i){
        System.out.println("人用"+i+"只"+s+"走路");
    }

}

测试类:

package cn.chenc.study;

import cn.chenc.study.entity.Animals;
import cn.chenc.study.entity.InterfaceFactory;
import cn.chenc.study.entity.Person;

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

public class Demo1 {

    public static void main(String[] args) throws Exception{
        //调用toString
        Class clazz=Class.forName("cn.chenc.study.entity.Person");
        Method method=clazz.getMethod("toString");
        Constructor constructor=clazz.getConstructor(String.class,int.class);
        Object object=constructor.newInstance("secret",21);
        System.out.println(method.invoke(object,null));
        //调用show
        method=clazz.getMethod("show",String.class,int.class);

        method.invoke(object,"chen",19);

        //接口测试,person实现animals
        Class[] interfaces= clazz.getInterfaces();
        Class childClass=interfaces.getClass();
        Class inter=interfaces[0];

        method=inter.getMethod("eat");
        method.invoke(object);

        //代理测试
        Animals proxy = (Animals) Proxy.newProxyInstance(clazz.getClassLoader(), interfaces, (proxy1, method1, args_temp) -> {
            Object result = method1.invoke(object, args_temp);
            return result;
        });
        proxy.run("脚", 2);

        //lanmbda 函数式接口
        lambdaTest((a) -> {
            //    return new Person();
            return String.valueOf(a);
        });

    }

    public static void lambdaTest(InterfaceFactory interfaceFactory){
        System.out.println(interfaceFactory.show(1));

    }
}

总结:

函数式接口:。

InterfaceFactory interfaceFactory=
(a) -> {
            //    return new Person();
            return String.valueOf(a);
        };实际上这里是创建了一个匿名的子类对象,并且实现了show方法,show方法的是参数int类型,返回值String类型。函数式接口有且只有一个抽象方法,可以有很多个非抽象方法,比如静态方法。在接口中,变量默认是puublic static final方法默认是public abstract

前三种都是通过指定className和method方法来实现的调用,如果进行传参还需要getMethod,感觉还是挺不灵活的。

如果使用动态代理的话,就可以直接使用接口来调用,并且还能实现方法的增强。

Proxy类就是用来创建一个代理对象的类,我们最常用的是newProxyInstance方法。

InvocationHandler也是动态代理一个很重要的接口,里面有一个invoke方法,我这里是使用了lambda表达式来实现了这个接口。

原文地址:https://www.cnblogs.com/secret-ChenC/p/12154347.html

时间: 2024-08-10 18:10:00

java反射-Method中的invoke方法的用法-以及函数式接口和lambda表达式的相关文章

Java 关于函数式接口与Lambda表达式之间的关系

java是一种面向对象的语言,java中的一切都是对象,即数组,每个类创建的实例也是对象.在java中定义的函数或方法不可能完全独立,也不能将方法函数作为参数或返回值给实例. 在java7及以前,我们一直都是通过匿名内部类把方法或函数当做参数传递,如下是一个线程实例. @Test public void testAnonymous() { new Thread(new Runnable() { @Override public void run() { System.out.println("匿

Java 函数式编程和Lambda表达式

1.Java 8最重要的新特性 Lambda表达式.接口改进(默认方法)和批数据处理. 2.函数式编程 本质上来说,编程关注两个维度:数据和数据上的操作. 面向对象的编程泛型强调让操作围绕数据,这样可以实现以类为单位的重用,当为类添加新的数据类型时,原有代码无需修改. 函数式编程是一种不同的编程模型,它以操作(函数)为中心,强调变量不变性.函数式编程的准则是不依赖外部的数据,也不改变外部数据的值.这一特性满足了多核并行程序设计的需求,因此能简化并行程序开发. 函数式编程用函数来表达所有的概念,完

Java函数式编程(Lambda表达式)小记

函数式编程 函数式编程(Functional Programming)是编程范式的一种.最常见的编程范式是命令式编程(Impera Programming),比如面向过程.面向对象编程都属于命令式编程,大家用得最多.最熟悉.函数式编程并非近几年的新技术或新思维,其诞生已有50多年时间. 在函数式编程里面,一切都是数学函数.当然,函数式编程语言里也可以有对象,但这些对象是不可变的——要么是函数参数要么是返回值.函数式编程语言里没有for等循环,而是通过递归.把函数当成参数传递的方式实现循环效果.

java反射机制中的动态代理

java反射机制中的动态代理 动态代理模式及其使用 步骤1:定义一个接口 //接口 interface Subject{ void action(); } 步骤2:定义一个接口的实现类,也就是被代理类 //被代理类 class RealSubject implements Subject { @Override public void action() { System.out.println("我是被代理类,请执行我"); } } 步骤3:定义一个实现InvocationHandle

Java 反射调用私有域和方法(setAccessible)

Java 反射调用私有域和方法(setAccessible) @author ixenos AccessibleObject类 Method.Field和Constructor类共同继承了AccessibleObject类,该基类有两个setAccessible方法能在运行时压制Java语言访问控制检查(Java language access control checks),从而能任意调用被私有化保护的方法.域和构造方法 public class AccessibleObjectextends

Java反射理解(五)-- 方法反射的基本操作

Java反射理解(五)-- 方法反射的基本操作 方法的反射 1. 如何获取某个方法 方法的名称和方法的参数列表才能唯一决定某个方法 2. 方法反射的操作 method.invoke(对象,参数列表) 举例 具体操作请看下面举例: import java.lang.reflect.Method; class A{ public void print(){ System.out.println("helloworld"); } public void print(int a,int b){

向Java枚举类型中添加新方法

除了不能继承enum之外,可将其看做一个常规类.甚至可以有main方法. 注意:必须先定义enum实例,实例的最后有一个分号. 下面是一个例子:返回对实例自身的描述,而非默认的toString返回枚举实例的名字. public enum Color { RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4); // 成员变量 private String nam

HTML5 canvas 中的arcTo()方法的用法

除了arc()之外,Canvas的绘图环境对象还提供了另一个用于创建圆弧路径的方法,那就是arcTo().改方法接受了5个参数: arcTo(x1,x2,y1,y2,radius) arcTo()方法的参数分别代表两个点击圆形半径.该方法一指定的半径来绘制一条圆弧,此圆弧与当前点到第一个点(x1,y1)的连线相切,而且第一个点到第二点(x2,y2)的连线也相切.该方法的这些特性,使得它非常适合用了绘制矩形的原角. 使用arcTo()方法: html: <!Doctyp html> <ht

[二] java8 函数式接口详解 函数接口详解 lambda表达式 匿名函数 方法引用使用含义 函数式接口实例 如何定义函数式接口

函数式接口详细定义 package java.lang; import java.lang.annotation.*; /** * An informative annotation type used to indicate that an interface * type declaration is intended to be a <i>functional interface</i> as * defined by the Java Language Specificat