Java 动态代理,invoke() 自动调用原理,invoke() 参数

4 篇文章 0 订阅
订阅专栏

Java 动态代理,invoke() 自动调用原理,invoke() 参数

本文介绍了静态代理和动态代理的概念,并且用代码、注释、图示和源码的方式来分析动态代理原理和invoke()自动调用原理。


学习动态代理,先从静态代理入手

静态代理

假如现在我们面临一个需求,把一个项目中所有访问数据库的方法都记录日志。最直接的方法是修改所有代码,在每个方法里面都加入写日志代码:

public class Dao {
	User findUserbyId(int id) {
		// 业务代码
		xxx;
		// 加入写日志代码
		xxx;
	}
	
}

但是这样工作量会很大,并且模块之间是耦合的,比如下次的需求是修改记录日志的内容,那么又要去修改所有业务代码,显然这种方法是不可取的。

如果不可以修改业务代码呢?

很容易就想到静态代理,写代理类对业务代码进行调用,我们用老师教学生举例子:

/**
* 老师接口,老师可以教学生
*/
public interface Teacher { 
    void teach();
}
/**
* 老师接口的实现类,具体实现 teach() 方法
*/
public class RealTeacher implements Teacher {
    @Override
    public void teach() {
        System.out.println("I am a teacher, I am teaching!");
    }
}
/**
* 老师代理对象,增强 teach() 方法
*/
public class TeacherProxy implements Teacher {
    Teacher teacher = new RealTeacher();
    @Override
    public void teach() {
    	// 这里 dosomething() 可以实现一些代理类的功能
    	dosomething();
    	// 这里执行 RealTeacher 的 teach() 方法
    	teacher.teach();
        dosomething();
    }
}
/**
* 测试代理类
*/
public class ProxyTest {
    public static void main(String args[]) {
    	Teacher teacher = new TeacherProxy();
    	// 这里执行代理类的 teach() 方法
    	teacher.teach();
    }
}

用图示表示上面静态代理的代码,可以描述为:

从图片和代码可以看出,这里只是用一个新对象去包含原来的 RealTeacher 对象,看似多此一举,但是确实一个不改变原来的代码,对方法进行增强的好办法。但是,如果我们要增强很多方法,比如文章开头的例子,需要对所有访问数据库的方法添加日志记录,如果用静态代理,要为每一个对象编写代理累,代码量十分庞大,也难以维护。

动态代理

既然为每一个需要代理的对象(下文通称为目标对象)都编写相应的代理类很麻烦,那么能不能不写死代理对象和目标对象,只写一个代理对象就可以使用不同的目标对象呢?
答案是可以的,就是用动态代理。动态代理的代理对象不依赖于目标对象,不和目标对象耦合。其原理是把目标对象的类型信息(比如接口)作为参数,利用 Java 支持的反射来创建代理对象,这样,就解除了代理对象和目标对象的耦合,一个代理对象可以适用一些列的目标对象。用图表示为:
在这里插入图片描述
如上图所示,目标对象作为一个参数,动态代理得到这个参数之后分成三步走:

  1. 获得目标对象的接口信息和类加载器,然后根据这两个信息来反射得到代理类的 Class
  2. 获得目标对象的 Class
  3. 根据1 2两步获得的接口,代理类 Class,目标类 Class 实例化一个代理对象

这样, 就创建了一个代理对象。从图中可以看出,动态代理并没有和目标对象绑定,而是把目标对象作为一个参数。

JDK 提供了 java.lang.reflect.InvocationHandler 接口和 java.lang.reflect.Proxy 类来实现上述反射等功能,其中 java.lang.reflect.InvovationHandler 接口用于绑定目标对象需要增强的方法,java.lang.reflect.Proxy 提供静态方法 NewProxyInstance() 用于创建一个代理类实例,这样,这个代理类实习就被创建出来并且通过嵌入 InvocationHandler 绑定了目标类的方法。
上面的静态代理代码的例子改成动态代理:

/**
 * 老师接口,老师可以教学生
 */
public interface Teacher {
    void teach();
}

/**
 * 老师接口的实现类,具体实现 teach() 方法
 */
public class RealTeacher implements Teacher {
    @Override
    public void teach() {
        // 老师正在教书
        System.out.println("I am a teacher, I am teaching!");
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * 代理类,根据接口等信息动态地创建代理对象,其中 MyProxy 是 InvocationHandler 的实现类,用于绑定方法
 */
public class MyProxy implements InvocationHandler {
    // tar用于接收目标类的参数
    private Object tar;

    // 绑定目标类,根据目标类的类加载器和接口创建代理对象,并返回
    public Object bind(Object target) {
        this.tar = target;
        // 注意:此处代码返回代理类
        return Proxy.newProxyInstance(tar.getClass().getClassLoader(), 
        tar.getClass().getInterfaces(), this);
    }
    // invoke() 方法用于方法的增强
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        // 执行一些方法
        System.out.println("Do something before");

        // 目标类的方法执行,这里实际上是执行目标对象的方法,
        // 也就是 bind(Object target)参数 object target 的方法
        result = method.invoke(tar, args);

        System.out.println("Do something after");
        return result;
    }
}


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

public class ProxyTest {
    public static void main(String[] args) throws Throwable {
        MyProxy proxy = new MyProxy();

        // 传入目标对象,进行绑定
        Teacher teacher = (Teacher)proxy.bind(new RealTeacher());

        // 执行代理对象的方法
        teacher.teach();
    }
}

测试函数的输出应该为:

Do something before
I am a teacher, I am teaching!
Do something after

改写成内部类的方式可以更清楚的看到:

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

public class ProxyTest {
    public static void main(String[] args) throws Throwable {
        // 这里能清楚地看到,目标对象 RealTeacher 是一个纯粹的参数
        Teacher teacher = (Teacher)getProxy(new RealTeacher());
        // teacher 是接口 Teacher 的一个实现类,
        // 完全从多态的角度也能想到执行的实际上是 RealTeacher 的 teach() 方法
        teacher.teach();
    }
    public static Object getProxy(Object target) throws Throwable{

        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object result = null;
                        System.out.println("Do something before");
                        result = method.invoke(target, args);
                        System.out.println("Do something after");
                        return result;
                    }
        });
    }
}

此源代码在 GitHub 上。
目标对象 RealTeacher 可以看成是一个纯粹的参数,不和代理类耦合。
在应用的时候,可以把具体实现过程忽略,把

Teacher teacher = (Teacher)getProxy(new RealTeacher());

看成一个黑箱,它输入一个目标类作为参数,返回一个实现了 Teacher 接口的代理类。到此为止,我们成功使用了动态代理,在没有和目标类 RealTeacher 绑定的情况下,创建了一个代理类,增强了 teach() 方法。

进一步深究代理类 teacher,invoke()

为了进一步探究生成的代理类 teacher 到底是什么一个情况,我们输出 teach 的一些类型信息:

    public static void main(String[] args) throws Throwable {
        // 这里能清楚地看到,目标对象 RealTeacher 是一个纯粹的参数
        Teacher teacher = (Teacher)getProxy(new RealTeacher());
        // teacher 是接口 Teacher 的一个实现类,
        // 完全从多态的角度也能想到执行的实际上是 RealTeacher 的 teach() 方法
        teacher.teach();

        System.out.println(teacher.getClass().getSuperclass());//输出是class java.lang.reflect.Proxy

        Class<?>[] interfaces = teacher.getClass().getInterfaces();

        for(Class<?> i : interfaces){
            System.out.println(i);// 输出是interface Teacher
        }

        Method[] methods = teacher.getClass().getDeclaredMethods();

        for (Method method : methods) {
            System.out.println(method);
            // 输出是:
            // public final boolean com.sun.proxy.$Proxy0.equals(java.lang.Object)
            // public final java.lang.String com.sun.proxy.$Proxy0.toString()
            // public final int com.sun.proxy.$Proxy0.hashCode()
            // public final void com.sun.proxy.$Proxy0.teach() 

        }
    }

由上述输出可以发现,

Teacher teacher = (Teacher)getProxy(new RealTeacher());

创建的代理类 teacher 实际是名字是 $Proxy0,它父类 Proxy,实现了 Teacher 接口,实现了 teach() 方法,所以代码

teacher.teach();

理所当然可以执行。

但是,我们知道代码 teacher.teach(); 最终执行了invoke()方法,那么这个teach()方法到底怎么和invoke()有关联的呢?

我们打开 teach 的方法 Proxy.newProxyInstance()源码的注释,关键的是这几行:

 * Returns a proxy instance for the specified interfaces
 * that dispatches method invocations to the specified invocation
 * handler.

@param   loader the class loader to define the proxy class
     * @param   interfaces the list of interfaces for the proxy class
     *          to implement
     * @param   h the invocation handler to dispatch method invocations to
     * @return  a proxy instance with the specified invocation handler of a
     *          proxy class that is defined by the specified class loader
     *          and that implements the specified interfaces

再看 Proxy 类的注释:

* {@code Proxy} provides static methods for creating objects that act like instances
 * of interfaces but allow for customized method invocation.
 * To create a proxy instance for some interface {@code Foo}:
 * <pre>{@code
 *     InvocationHandler handler = new MyInvocationHandler(...);
 *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
 *                                          new Class<?>[] { Foo.class },
 *                                          handler);
 * }</pre>
 *
 * <p>
 * A <em>proxy class</em> is a class created at runtime that implements a specified
 * list of interfaces, known as <em>proxy interfaces</em>. A <em>proxy instance</em>
 * is an instance of a proxy class.
 *
 * Each proxy instance has an associated <i>invocation handler</i>
 * object, which implements the interface {@link InvocationHandler}.
 * A method invocation on a proxy instance through one of its proxy
 * interfaces will be dispatched to the {@link InvocationHandler#invoke
 * invoke} method of the instance's invocation handler, passing the proxy
 * instance, a {@code java.lang.reflect.Method} object identifying
 * the method that was invoked, and an array of type {@code Object}
 * containing the arguments.  The invocation handler processes the
 * encoded method invocation as appropriate and the result that it
 * returns will be returned as the result of the method invocation on
 * the proxy instance.
 *

由注释发现,Proxy.newProxyInstance()方法返回一个代理对象的实例,这个实例是和一个特殊的 InvocationHandler 相关的,再回看我们写的代码:
在这里插入图片描述
我们实例化的匿名内部类 InvocationHandler 正是有 invoke() 方法,所以刚才的问题:

那么这个teach()方法到底怎么和invoke()有关联的呢?

是因为代理对象实例 teacher 的父类是 Proxy,由 Proxy 去和我们实例化的匿名内部类 InvocationHandler 去关联

再看实例对象 teacher(也就是 $Proxy0 )的反编译代码:(此代码来自 这里)

public final class $Proxy0 extends Proxy implements Subject {  
    private static Method m1;  
    private static Method m0;  
    private static Method m3;  
    private static Method m2;  
  
    static {  
        try {  
            m1 = Class.forName("java.lang.Object").getMethod("equals",  
                    new Class[] { Class.forName("java.lang.Object") });  
  
            m0 = Class.forName("java.lang.Object").getMethod("hashCode",  
                    new Class[0]);  
  
            m3 = Class.forName("***.RealSubject").getMethod("request",  
                    new Class[0]);  
  
            m2 = Class.forName("java.lang.Object").getMethod("toString",  
                    new Class[0]);  
  
        } catch (NoSuchMethodException nosuchmethodexception) {  
            throw new NoSuchMethodError(nosuchmethodexception.getMessage());  
        } catch (ClassNotFoundException classnotfoundexception) {  
            throw new NoClassDefFoundError(classnotfoundexception.getMessage());  
        }  
    } //static  
  
    public $Proxy0(InvocationHandler invocationhandler) {  
        super(invocationhandler);  
    }  
  
    @Override  
    public final boolean equals(Object obj) {  
        try {  
            return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue();  
        } catch (Throwable throwable) {  
            throw new UndeclaredThrowableException(throwable);  
        }  
    }  
  
    @Override  
    public final int hashCode() {  
        try {  
            return ((Integer) super.h.invoke(this, m0, null)).intValue();  
        } catch (Throwable throwable) {  
            throw new UndeclaredThrowableException(throwable);  
        }  
    }  
  
    public final void teach() {  
        try {  
            super.h.invoke(this, m3, null);  
            return;  
        } catch (Error e) {  
        } catch (Throwable throwable) {  
            throw new UndeclaredThrowableException(throwable);  
        }  
    }  
  
    @Override  
    public final String toString() {  
        try {  
            return (String) super.h.invoke(this, m2, null);  
        } catch (Throwable throwable) {  
            throw new UndeclaredThrowableException(throwable);  
        }  
    }  
}  

也验证了当执行 teacher.teach() 的时候,也就是执行 $Proxy0.teach() 的时候,会执行 super.h.invoke(),也就是执行父类 Proxy 的 invoke(),而父类 Proxy 是和 InvocationHandler 是关联的,总结为:

teacher.teach() --> $Proxy0.teach() --> super.h.invoke() --> proxy.invoke() --> invocationHandler.invoke()

图示可以表示为:
在这里插入图片描述

invoke() 的参数

从代码可以看出,invoke() 方法有三个参数:

  • Object proxy
  • Method method
  • Object[] args

我们在 invoke() 中输出 proxy 的名字:

return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    	// 输出proxy名字
                        System.out.println(proxy.getClass().getName());
                        
                        Object result = null;
                        System.out.println("Do something before1");
                        result = method.invoke(target, args);
                        System.out.println("Do something after1");
                        return result;
                    }
        });

输出是:
在这里插入图片描述
上文说代理类名字是 $Proxy0,所以实际上 proxy 参数就是代指反射创建的代理类 $Proxy0,之所以不用 this,因为 this 代表的是 InvocationHandler() 这个匿名内部类的实例。

同样的,我们看 $Proxy0 的反编译代码:
在这里插入图片描述
这个代码中的this就是 $Proxy0 对象本身,也是作为 invoke() 的第一个参数,也就是 proxy 进行参数传递。所以也能得到 proxy 参数就是代指反射创建的代理类 $Proxy0 的结论。

对于第二个参数 method,我们看 Method 的注释:

 * 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).

可以看出第二个参数 method 用于绑定的目标类的方法

第三个参数是方法的参数

总结

代理模式是一种不改变源代码对方法进行增强的好方法,但是静态代理代理类和目标类是绑定耦合的。

动态代理的特点是:

  • 利用目标类的接口信息,通过反射创建代理类
  • 可以把代理类固定下来,不因为业务代码量庞大而复杂,便于扩展、修改和维护。
  • 方便实现 RPC 和 AOP
  • 源码难以理解
java动态代理InvocationHandler和Proxy详解
jonathan的专栏
08-30 3178
今天在整理代理模式时,发现以前对于InvocationHandler中的invoke()方法理解很肤浅,所以重新梳理学习了下. InvocationHandler接口 InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口,每一个proxy代理实例都有一个关联的调用处理程序. 在代理实例调用方法时,方法调用被编码分派到调用处理程序的invoke()方法. 每一个动...
动态代理invoke 方法详解、动态代理流程梳理
weixin_57667101的博客
11-14 1097
动态代理invoke 方法详解、动态代理流程梳理
java动态代理invoke以及源码理解
jz6666jz的博客
07-29 635
invoke 方法介绍 想要知道 invoke方法为什么会自动调用我们先要来了解一下这个方法 public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) 首先 该方法来自于接口InvocationHandler ,该接口中仅有一个invoke方法 ,该方法中有三个参数 1 2 3 4 5 @param proxy the proxy instance that
java中Method.invoke方法参数解析
Moneys的博客
01-25 9382
通过反射的机制,可以通过invoke方法来调用类的函数。invoke函数的第一个参数是方法的实例,如果该方法是静态方法,可以用null或者用类来代替,第二个参数是变长的,是调用该方法的参数。 package com.tn.class; import java.lang.reflect.Method; import java.util.Arrays; public class Client { public static void main(String[] args) throws Except
深入理解Java中的反射机制和使用原理!详细解析invoke方法的执行和使用(1)
最新发布
2401_84102400的博客
05-03 1075
本人面试腾讯,阿里,百度等企业总结下来的面试经历,都是真实的,分享给大家!本人面试腾讯,阿里,百度等企业总结下来的面试经历,都是真实的,分享给大家![外链图片转存中…(img-iHzWIW4M-1714740326074)][外链图片转存中…(img-zV0SI1jM-1714740326075)][外链图片转存中…(img-hswUJtRM-1714740326075)][外链图片转存中…(img-B0t819X6-1714740326076)]
动态代理模式newProxyInstance及invoke方法参数详解
mRambo的博客
07-19 5332
动态代理概述: Java提供的动态代理类Proxy: Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods. 代理类Proxy提供静态方法用于创建动态代理子类和对象。它也是所有通过这些静态方法所创建的动态代理子类的父类。 其中一个最
C#中反射里的invoke方法的参数
シ❤゛甜虾的个人博客
05-18 3543
对于外部调用的动态库应用反射时要用到Assembly.LoadFile(),然后才是获取类型、执行方法等; 当用反射创建当前程序集中对象实例或执行某个类下静态方法时只需通过Type.GetType("类的完整名")。 using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; //一
JavaWeb学习-动态代理-2-invoke()方法和动态代理Waiter类练习
Anthony_tester的博客
08-29 469
这篇来学习invoke()方法中三个参数具体含义和基本使用,然后做一个动态代理的练习,写一个服务员类相关的动态代理实现过程。 invoke()方法 详细来看看这个,前面知道InvocationHandler是一个接口,这个接口只有一个方法,那就是invoke()。 我们开详细看看这个invoke()方法中三个参数和返回值。我们先来在A接口中写一个aaa()方法。 package...
UnityC#学习之--Invoke
wanghexuan的博客
01-12 1950
会延时执行的函数 是 MonoBehaviour 基类中实现好的方法 Invoke 参数一:函数名 字符串 参数二:延迟时间 秒为单位 void Start() { Invoke("DelayDoSomething", 1); } private void DelayDoSomething() { print("延时执行的函数"); TestFun(2); } private
Java动态代理语法Proxy类原理详解
08-19
InvocationHandler接口是Java动态代理语法的核心组件,它提供了一个invoke()方法,该方法决定了代理对象如何处理代理传递过来的方法调用。该方法需要三个参数:proxy表示代理对象,method表示代理对象调用的方法,...
Java Method类及invoke方法原理解析
08-18
Java Method类及invoke方法原理解析 Java Method类是Java反射机制中的一个重要组件,它提供了对Java方法的抽象表示和操作能力。通过Method类,可以获取方法的信息、调用方法、设置方法的访问权限等。 Method类的...
Java JDK动态代理实现原理实例解析
08-19
Java JDK动态代理实现原理实例解析 Java JDK动态代理实现原理实例解析是指通过Java JDK提供的代理机制来实现动态代理原理和实例解析。动态代理是一种非常重要的设计模式,它可以在运行时生成代理类,从而实现了...
利用java反射机制实现自动调用类的简单方法
09-01
Java反射机制是Java语言提供的一种...通过上述步骤,我们可以看到Java反射机制如何实现动态调用类的简单方法。这种技术在需要动态执行代码或实现通用功能的场景下非常有用,但使用时应权衡其带来的安全性和性能影响。
Java 动态代理详解(学习资料)
06-17
JDK 动态代理JDK 提供了 java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口来支持动态代理。Proxy 类用于创建一个代理对象,而 InvocationHandler 接口则定义了代理对象的方法调用处理逻辑。...
浅谈java继承机制——通过super调用父类方法
热门推荐
weixin_43905219的博客
11-09 1万+
最近在看代码的时候遇到一个天坑,由于习惯性思维,可能大部分人都会掉近这个坑,所以拿出来记录一下 子类使用super调用的父类方法里,再调用父类的方法 先来看一段代码(该段代码只是作为测试用,正常编码时类名一定要规范编写) package supertetst; /** * @Author: x1aolone * @Date: 2019/11/8 22:11 */ class father...
强大的 Python 任务自动化工具!invoke 十分钟入门指南
Python猫
02-05 1260
????“Python猫” ,一个值得加星标的公众号接着前面的《tox 教程》,以及刚翻译好的《nox文档》,我们继续聊聊 Python 任务自动化的话题。nox 的作者在去年的 Py...
java动态代理中的invoke方法是如何被自动调用
a380425381的博客
05-21 175
转载:http://www.shangxueba.com/jingyan/1853835.html 一、动态代理与静态代理的区别。(1)Proxy类的代码被固定下来,不会因为业务的逐渐庞大而庞大;(2)可以实现AOP编程,这是静态代理无法实现的;(3)解耦,如果用在web业务下,可以实现数据层和业务层的分离。(4)动态代理的优势就是实现无侵入式的代码扩展。 静态代理这个模式本身有...
java 反射 method invoke 变长参数
shi_xin的专栏
04-09 2986
看下,反射中可能遇到的一个问题:一个类,专门用来进行测试反射相关code:public class InvokeClass { private final static String TAG = "InvokeClassDemo"; public void printString(String... args) { Log.d(TAG, "args len: ...
java 动态代理原理
02-22
Java动态代理是一种在运行时创建代理对象的机制,它允许我们在不修改源代码的情况下,对目标对象进行增强或拦截。动态代理主要依赖于Java的反射机制。 Java动态代理原理如下: 1. 定义一个接口:首先需要定义一个接口,该接口是目标对象和代理对象共同实现的接口。 2. 实现InvocationHandler接口:创建一个实现InvocationHandler接口的类,该类负责实现代理对象的具体操作逻辑。 3. 获取代理对象:通过Proxy类的静态方法newProxyInstance()获取代理对象。该方法需要传入三个参数:ClassLoader,用于加载代理类;Class[],用于指定代理类实现的接口;InvocationHandler,用于指定代理对象的具体操作逻辑。 4. 调用代理对象方法:通过代理对象调用方法时,会自动触发InvocationHandler中的invoke()方法,从而实现对目标对象方法的增强或拦截。 动态代理原理就是通过在运行时生成代理类来实现对目标对象的代理。在调用代理对象的方法时,实际上是调用了InvocationHandler中的invoke()方法,从而实现了对目标对象方法的增强或拦截。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • python十分简单实现十进制到任意进制的转换 29703
  • 编译原理NFA确定化 18973
  • 编译原理 LL1文法的判断和句子识别 16653
  • 随机森林原理及其用于分类问题的matlab实现 14706
  • BP神经网络实现分类问题(python) 14672

分类专栏

  • Java 4篇
  • 数据结构和算法 15篇
  • 后端技术栈 1篇
  • 算法题 11篇
  • Redis
  • 机器学习 8篇
  • 编程日记 13篇
  • 小程序 5篇

最新评论

  • KNN分类算法原理及其Matlab实现

    Blush_teng: 您好,请问数据集可以分享一下不,感激不尽啊,谢谢你 2237135514@qq.com🥺

  • Java 动态代理,invoke() 自动调用原理,invoke() 参数

    爱辣条的小绵狼: 请收下我的膝盖

  • Java 动态代理,invoke() 自动调用原理,invoke() 参数

    科学家达闻西: 源码看不太懂,但是知道了大概,知道怎么用这个动态代理了。有时间在深究吧

  • Java 动态代理,invoke() 自动调用原理,invoke() 参数

    zz的学习记录: 看来很激动

  • python基础--实现大数到任意进制的转换

    sz.fang: 您好,大数必须是10进制么,我想16->10进制可以么

大家在看

  • 基于Java中的SSM框架实现萌宠优购系统项目【项目源码】计算机毕业设计
  • 项目从接收到发布的流程
  • 基于springboot实现火车票订票系统项目【项目源码+论文说明】计算机毕业设计
  • 程序员最趁手的SVM算法,学完你会哭着感谢努力的自己!
  • 提高LabVIEW程序可靠性 467

最新文章

  • Java 交替打印两个线程的三儿种方法
  • Top K 问题一网打尽
  • RPC 原理,Demo 演示,为什么 RPC 用动态代理
2021年4篇
2020年10篇
2019年3篇
2018年21篇
2017年9篇
2016年12篇

目录

目录

评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

聚圣源宝宝起名免费试验赤足惊魂副食店起名大全集红米k30pro参数敦刻尔克行动超载1人扣多少分和罚款多少起姓名诗意男孩渭南地图起个带财的名字木业公司起名大全免费盛况个人资料郑州限号2021最新限号2月南楚辞北诗经起名给宝宝免费起名软件免费拜师九叔潘姓女孩起名2020反黑路人甲粤语社区管理joker延时喷剂蟠桃园喋血钱塘江演员表公司起名同名不同行业可以吗丝袜文学女装店起名时尚简单三国之宅行天下海龟交易法则下载鲈鱼清蒸的做法步骤湖北大学职业技术学院和平精英变声器凤思吾夜凌寻小说免费阅读无弹窗淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻让美丽中国“从细节出发”清明节放假3天调休1天男孩疑遭霸凌 家长讨说法被踢出群国产伟哥去年销售近13亿网友建议重庆地铁不准乘客携带菜筐雅江山火三名扑火人员牺牲系谣言代拍被何赛飞拿着魔杖追着打月嫂回应掌掴婴儿是在赶虫子山西高速一大巴发生事故 已致13死高中生被打伤下体休学 邯郸通报李梦为奥运任务婉拒WNBA邀请19岁小伙救下5人后溺亡 多方发声王树国3次鞠躬告别西交大师生单亲妈妈陷入热恋 14岁儿子报警315晚会后胖东来又人满为患了倪萍分享减重40斤方法王楚钦登顶三项第一今日春分两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?周杰伦一审败诉网易房客欠租失踪 房东直发愁男子持台球杆殴打2名女店员被抓男子被猫抓伤后确诊“猫抓病”“重生之我在北大当嫡校长”槽头肉企业被曝光前生意红火男孩8年未见母亲被告知被遗忘恒大被罚41.75亿到底怎么缴网友洛杉矶偶遇贾玲杨倩无缘巴黎奥运张立群任西安交通大学校长黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发妈妈回应孩子在校撞护栏坠楼考生莫言也上北大硕士复试名单了韩国首次吊销离岗医生执照奥巴马现身唐宁街 黑色着装引猜测沈阳一轿车冲入人行道致3死2伤阿根廷将发行1万与2万面值的纸币外国人感慨凌晨的中国很安全男子被流浪猫绊倒 投喂者赔24万手机成瘾是影响睡眠质量重要因素春分“立蛋”成功率更高?胖东来员工每周单休无小长假“开封王婆”爆火:促成四五十对专家建议不必谈骨泥色变浙江一高校内汽车冲撞行人 多人受伤许家印被限制高消费

聚圣源 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化