invoke 用法
- 格式:doc
- 大小:141.00 KB
- 文档页数:15
python 类中的 invoke方法用法在 Python 中,类是一种创建对象的机制,而方法则是对象的行为。
在类中定义的方法可以接受参数并返回结果。
`invoke` 方法是类中的一个特殊方法,通常用于在运行时动态地调用其他方法或函数。
一、`invoke` 方法的基本用法`invoke` 方法通常用于在运行时动态地调用类中的其他方法或函数。
它接受一个或多个参数,并返回一个结果。
以下是一个简单的示例:```pythonclass MyClass:def __init__(self):self.value = "Hello, world!"def my_method(self):return "This is my method."def invoke(self, other_method):# 调用其他方法或函数result = other_method()return result```在上面的示例中,我们定义了一个 `MyClass` 类,其中包含一个`my_method` 方法和一个 `invoke` 方法。
`invoke` 方法接受一个名为 `other_method` 的参数,并调用该方法。
在 `invoke` 方法中,我们简单地调用了 `other_method()` 并将返回的结果返回给调用者。
二、使用 `invoke` 方法调用其他方法或函数要使用 `invoke` 方法调用其他方法或函数,只需创建一个`MyClass` 对象,并传递要调用的方法名作为参数即可。
例如:```pythonobj = MyClass()result = obj.invoke(my_method) # 调用 my_method 方法print(result) # 输出 "This is my method."```在上面的示例中,我们创建了一个 `MyClass` 对象,并使用`invoke` 方法调用了 `my_method` 方法。
C#中Invoke委托的⽤法()invoke的作⽤:在多线程编程中,我们经常要在⼯作线程中去更新界⾯显⽰,⽽在多线程中直接调⽤界⾯控件的⽅法是错误的做法,Invoke 和 BeginInvoke 就是为了解决这个问题⽽出现的,使你在多线程中安全的更新界⾯显⽰。
.invoke和begininvoke的使⽤有两种情况:1. control中的invoke、begininvoke。
2. delegrate中的invoke、begininvoke。
这两种情况是不同的,我们这⾥要讲的是第1种。
下⾯我们在来说下.NET中对invoke和begininvoke的官⽅定义。
control.invoke(参数delegate)⽅法:在拥有此控件的基础窗⼝句柄的线程上执⾏指定的委托。
control.begininvoke(参数delegate)⽅法:在创建控件的基础句柄所在线程上异步执⾏指定委托。
根据这两个概念我们⼤致理解invoke表是同步、begininvoke表⽰异步。
如果你的后台线程在更新⼀个UI控件的状态后不需要等待,⽽是要继续往下处理,那么你就应该使⽤BeginInvoke来进⾏异步处理。
如果你的后台线程需要操作UI控件,并且需要等到该操作执⾏完毕才能继续执⾏,那么你就应该使⽤Invoke。
invoke 例⼦:private void button1_Click(object sender, EventArgs e){MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"AAA");invokeThread = new Thread(new ThreadStart(StartMethod));invokeThread.Start();string a = string.Empty;for (int i = 0; i < 3; i++) //调整循环次数,看的会更清楚{Thread.Sleep(1000);a = a + "B";}MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+a);}private void StartMethod(){MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"CCC");button1.Invoke(new invokeDelegate(invokeMethod));MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"DDD");}private void invokeMethod(){//Thread.Sleep(3000);MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString() + "EEE");}结论:我们运⾏后,看下程序的运⾏顺序,1AAA->3CCC和1BBB->1EEE ->3DDD 。
java invoke的用法Java中的invoke方法是一种动态调用方法的方式,它允许我们在运行时动态地指定一个对象、方法和参数来执行方法。
invoke方法的灵活性使得它在许多情况下非常有用,比如反射、代理等。
本文将一步一步地回答关于invoke方法的用法,包括如何使用invoke方法、invoke的参数以及使用invoke的注意事项等。
一、什么是invoke方法在Java中,invoke方法是Method类和Constructor类的一个成员方法,它用于调用指定对象的方法或构造方法。
通过invoke方法,我们可以在运行时动态地调用方法,而不需要提前知道方法的具体实现。
二、invoke方法的基本用法1. 获取Method对象或Constructor对象在使用invoke方法之前,我们首先需要获取想要调用的方法或构造方法的Method对象或Constructor对象。
Method对象或Constructor对象可以通过Class类的getMethod、getDeclaredMethod、getConstructor和getDeclaredConstructor等方法来获取。
其中,getMethod和getConstructor 方法是获取公有的方法或构造方法,getDeclaredMethod和getDeclaredConstructor方法是获取所有方法或构造方法(包括私有的)。
2. 调用方法或构造方法通过Method对象调用方法或Constructor对象调用构造方法,需要使用invoke 方法。
invoke方法的基本格式如下:Object invoke(Object obj, Object... args)其中,obj是指定对象(或null,如果方法是静态的),args是方法的参数。
3. 处理返回值invoke方法会返回方法的执行结果,如果方法没有返回值,则返回null。
如果方法有返回值,我们可以根据方法的返回类型进行强制类型转换。
linux invoke用法Linux是一个强大的操作系统,提供了许多命令行工具来帮助用户进行各种操作。
Invoke是其中一个常用的命令,用于在Linux中执行外部程序或脚本。
在本篇文章中,我们将介绍Invoke的基本用法、参数和注意事项。
一、基本用法Invoke的基本用法是使用“invoke”命令后跟要执行的程序或脚本的路径。
例如,如果要执行名为“myscript.sh”的脚本,可以运行以下命令:```shellinvoke/path/to/myscript.sh```Invoke还支持使用“-c”参数来执行一个包含多个命令的字符串。
例如:```shellinvoke-c"command1;command2;command3"```这将依次执行“command1”、“command2”和“command3”。
二、参数1.路径:要执行的程序或脚本的路径是必需的。
您可以通过在程序或脚本名称前加上绝对路径或相对路径来指定其位置。
2.选项:Invoke提供了许多选项,可以用来控制执行程序的方式。
例如,“-f”选项可以强制执行程序,即使其输出被重定向到stdout。
3.参数:如果您要执行的程序接受参数,可以使用Invoke的“-a”参数将它们传递给它。
例如:```shellinvoke-aarg1arg2myprogram```这将在运行myprogram时将arg1和arg2作为参数传递给它。
三、注意事项1.权限:Invoke需要足够的权限来执行程序或脚本。
如果您没有足够的权限,您可能需要使用sudo命令或以root用户身份运行Invoke。
2.错误输出:Invoke将错误输出重定向到stderr,而不是将其显示在屏幕上。
您可以使用“-e”选项来捕获所有错误输出,并将其显示在屏幕上。
例如:```shellinvoke-emyprogram>error.log2>&1```这将把myprogram的输出重定向到一个名为error.log的文件中,并将所有错误输出都包含在该文件中。
invoke函数invoke函数是一种在JavaScript开发中广泛使用的函数,它可以用于调用函数。
在一定程度上,它是一种处理函数参数的技术,可以帮助用户编写更紧凑的代码,以及更好地处理函数的参数。
本文将重点介绍invoke函数的用法,以及它们的应用场景。
首先,让我们来看看invoke函数的概念:invoke函数是一种特殊的函数,可以以不同的方式调用一个函数,从而达到不同的目的。
换句话说,它可以用来模拟函数调用,也可以用来传递参数到函数中。
invoke函数可以使用函数表达式调用,也可以使用函数指针调用。
两种方式都可以用来传参或者传入特定的参数。
简单来说,函数表达式可用于在函数内部定义一个函数,而函数指针可以被用来调用一个函数,这样就可以把参数传入到函数中去。
invoke函数可以接受不同类型的参数,包括字符串、数值、对象、数组和函数指针。
它也可以传入一个对象作为参数,以便在函数内部使用该对象的属性和方法。
invoke函数一般应用在参数派发和多态函数上。
参数派发是指在函数调用时分配不同的参数,这样可以达到适当的执行效果。
多态函数是指能够用不同参数执行相同结果的函数。
另外,有时候在传递多个参数的情况下,我们可以在调用函数之前使用invoke函数,以便把参数放到一个数组中,以更方便的传入参数。
这也是一种非常有用的方法。
invoke函数在JavaScript应用开发中起到了非常重要的作用,它可以让用户编写更紧凑的代码,以及更好地处理函数的参数,进而提高程序的性能和可扩展性。
对于invoke函数的使用,应该注意的是要保证使用invoke函数的时候,函数名拼写正确,并且参数类型匹配。
同时,还应该考虑函数的命名,返回值设置正确。
这样可以保证在调用函数的时候更加可靠。
总之,invoke函数是一种JavaScript开发中常用的函数,它可以让用户编写更紧凑的代码,以及更好地处理函数的参数。
invoke函数有多种应用场景,用户可以根据自身的需求选择合适的使用方式。
Kotlin中的invoke用法是一种特殊的方法,允许我们将对象作为函数调用。
这种方法在Kotlin中被称为“函数式编程”的特性之一。
当我们想要将对象作为函数调用时,我们需要定义一个包含invoke方法的对象。
这个方法可以通过使用()运算符来调用,就像调用普通函数一样。
invoke方法在Kotlin中有很多用途。
它可以用于简化代码,提高代码可读性,以及在需要传递函数作为参数的高阶函数中方便地使用对象。
下面是一些使用invoke方法的示例:定义一个包含invoke方法的对象我们可以定义一个对象,并为其添加一个invoke方法,如下所示:kotlinobject MyObject {operator fun invoke(): String {return "Hello, World!"}}在上面的代码中,我们定义了一个名为MyObject的对象,并为其添加了一个invoke 方法。
该方法返回一个字符串"Hello, World!"。
由于我们使用了operator关键字,Kotlin 会自动将该对象转换为函数调用。
调用包含invoke方法的对象要调用包含invoke方法的对象,我们可以像调用普通函数一样使用()运算符:kotlinfun main() {val result = MyObject() // 调用MyObject对象的invoke方法,并将返回值存储在result变量中println(result) // 输出"Hello, World!"}在上面的代码中,我们像调用普通函数一样调用了MyObject对象。
由于该对象包含一个invoke方法,Kotlin会自动调用该方法并返回结果。
我们将结果存储在名为result的变量中,并将其输出到控制台。
C#关于InvokeInvoke的本质只是⼀个⽅法,⽅法⼀定是要通过对象来调⽤的。
什么时候⽤?⼀般来说,Invoke其实⽤法只有两种情况:Control的InvokeDelegate的Invoke也就是说,Invoke前⾯要么是⼀个控件,要么是⼀个委托对象。
为什么要⽤?1、Control的Invoke Control的Invoke⼀般⽤于解决跨线程访问的问题,⽐如你想操作⼀个按钮button,你就要⽤button.Invoke,你想操作⼀个⽂本label,你就要⽤label.Invoke.但是⼤家会发现很⿇烦,如果我既然想操作button,⼜操作label,能不能写在⼀起呢?有没有更简单的⽅法呢?其实主窗体使⼀个Form,Form⾃然也是继承了Control的,所以Form也有Invoke的⽅法,如果你想省点事,就可以直接调⽤Form.Invoke,这就是常见的this.Invoke.为什么有的Invoke前⾯啥都没有?其实前⾯是this,只不过省略了.2、Delegate的Invoke Delegate的Invoke其实就是从线程池中调⽤委托⽅法执⾏,Invoke是同步的⽅法,会卡住调⽤它的UI线程。
代码如下1public delegate void TestDelegateInvoke();23private void DelegateInvokeMethod()4 {5 Thread.Sleep(5000);6 }78private void btn_DelegateInvoke_Click(object sender , EventArgs e)9 {10 TestDelegateInvoke testDelegate = new TestDelegateInvoke(DelegateInvokeMethod);1112 testDelegate.Invoke();13 } 点击按钮运⾏之后,你会发现UI界⾯会卡住5秒钟。
Invoke 用法讲解Invoke /In’vəuk/名词: invoker过去式: invoked过去分词: invoked现在分词: invoking第三人称单数: invokes1, invoke sth (against) sb to mention or use a law, rule, etc. As a reason for doing sth 援引,援用(法律、规则等作为行动理由)2, to mention a person, a theory, an example, etc. To support your opinions or ideas, or as a reason for sth 提及,援引(某人、某理论、实例等作为支持)3, to mention sb’s name to make people feel a particular thing or act in a particular way 提出(某人的名字,以激发某种感觉或行动)4, to make a request (for help) to sb, especially a god 向(某人)请求帮助,(尤指)祈求神助5, to make sb have a particular feeling or imagine a particular feeling or imagine a particular scene 使产生,唤起(感情或想象)6, to use or apply sth 使用,应用7, to begin to run a program, etc. 调用,激活8, to make evil appera by using magic 用法术召唤(魔鬼)用作及物动词 (vt.)1.The government has invoked the official secret act in having the book banned.政府援引国家机密保密法以禁该书。
invoke英[ɪnˈvəʊk] 美[ɪnˈvoʊk]vt.乞灵,祈求;提出或授引…以支持或证明;召鬼;借助网络调用;恳求;祈求;唤起过去式:invoked 过去分词:invoked 现在分词:invoking 第三人称单数:invokes派生词:invoker 报错语源late 15th cent.: from French invoquer, from Latin invocare, from in- 'upon' + vocare 'to call'柯林斯高阶英汉双解学习词典英汉双向大词典vt.1. 援引, 援用;行使(权利等)(法律、规则等作为行动理由)She had invoked the law in her own defence.她援引法律为自己辩护。
2. 向(某人)请求帮助;(尤指)祈求神助3. 恳求;乞求She invoked their help.她恳求他们帮忙。
vt. & vi.1. 提及,援引(某人、某理论、实例等作为支持)2. 提出(某人的名字,以激发某种感觉或行动)3. 使产生,唤起,引起(感情或想像)4. 使用;应用5. . 调用;激活6. 用法术召唤(魔鬼)英英释义行业释义网络释义Verb1. evoke or call forth, with or as if by magic;2. cite as an authority; resort to;3. request earnestly (something from somebody); ask for aid or protection;词根:vok=call/voice,表示"出声,叫喊,看"同根词adj.invocatory祈求的, 祈愿的(invoc=invoke[v.祈求,恳求,[法律的]实施生效]+atory表形容词→adj.祈求的, 祈愿的)revocable可废除的(revoc=revoke[v.废除,取消]+able能……的→adj.可废除的) provocative激怒的,挑战的(provoc=provoke[v.激怒,刺激]+ative……的→adj.激怒的,挑战的) n.equivoke双关语, 含糊措辞(equi平等+vok出声,叫喊,看+e→有两种声音→双关语)invoke祈求,恳求,[法律的]实施生效(in进+vok出声,叫喊,看+e→喊进去,请求) convoke召集[会议] (con共同+vok出声,叫喊,看+e→喊到一起→召集)evoke唤起[回忆,感情等];引起(e出+vok出声,叫喊,看+e→喊出思想等)。
invoke的用法:动词,1,to use a law, principle etc. to support your opinions or actions援引(法律、原则等以支持自己的意见或行动)2,to ask for help from someone, especially a god祈求(尤指神的)帮助,主要用于文学方面。
如:1,First of all, we invoke Dalton's Law.首先提到的是Dalton定律。
2,It's reasonable, I think, to invoke Dr. Johnson here, Samuel Johnson, who writes in his Life of Milton that Milton's unskillful allegory appears to be one of the greatest faults ofthe poem.我认为在这引用塞缪尔·约翰逊的话是很合理的,他一生都在写关于弥尔顿的文章,他指出弥尔顿不熟练的寓言成为了这部诗的大败笔之一。
3,That is to say, we're going to focus on the question of what a poem is, and the question "What criteria should we invoke in order to read it for the best and correctly?"换句话说,我们将把注意力集中在,“什么是诗歌“,和“为了读懂诗歌,我们需要具备哪些素质“的问题上“。
4,When I call or invoke a function, think of it as creating a local table.当我调用一个函数时,想象一下它是在这里创建了一个局部表。
java中invoke方法(原创实用版4篇)篇1 目录1.Java 中 invoke 方法的概述2.invoke 方法的作用3.invoke 方法的使用方法4.invoke 方法的注意事项5.示例代码篇1正文一、Java 中 invoke 方法的概述在 Java 编程语言中,invoke 方法是一个非常实用的方法,它允许我们在运行时动态地调用对象的方法。
通过 invoke 方法,我们可以实现灵活的编程方式,提高代码的可读性和可维护性。
二、invoke 方法的作用invoke 方法的主要作用是动态地调用对象的方法。
在 Java 中,对象可以看作是一个类实例,类实例包含了类的属性和方法。
通常情况下,我们需要通过对象名调用方法,但是这样会导致代码的耦合度较高,不利于代码的维护。
而通过 invoke 方法,我们可以在运行时动态地调用对象的方法,从而降低代码的耦合度。
三、invoke 方法的使用方法要使用 invoke 方法,我们需要首先创建一个对象,然后通过该对象调用 invoke 方法。
invoke 方法的语法如下:```javaObject.invoke(Object obj, String methodName,Class<?>...parameterTypes)```其中,参数 obj 表示要调用的对象,methodName 表示要调用的方法名,parameterTypes 表示方法的参数类型。
四、invoke 方法的注意事项在使用 invoke 方法时,我们需要注意以下几点:1.obj 参数必须是一个对象实例,不能是类或接口。
2.methodName 参数表示要调用的方法名,需要与 obj 参数对应的类中的方法名一致。
3.parameterTypes 参数表示方法的参数类型,如果方法没有参数,则该参数为空。
参数类型需要与方法定义时的参数类型一致。
五、示例代码下面是一个使用 invoke 方法的示例代码:```javapublic class InvokeExample {public static void main(String[] args) {// 创建一个对象实例MyObject obj = new MyObject();// 使用 invoke 方法调用对象的方法Object result = obj.invoke("testMethod",String.class);// 输出调用结果System.out.println(result);}}class MyObject {public String testMethod(String param) {return "Hello, " + param;}}```在这个示例中,我们通过 invoke 方法动态地调用了 MyObject 对象的 testMethod 方法,并传入了一个 String 类型的参数。
invoke方法
Invoke法是一种特定类型的函数,可以使用它来调用某些函数或方法,同时可以传递参数。
Invoke法主要用于面向对象编程,避免写大量的重复代码。
一般而言,Invoke方法都是定义在接口中。
一个 Invoke法通常可以在多个类中实现,允许它们施加不同的操作或功能。
在面向对象编程中,Invoke法可以用来在不同对象之间传输信息,也可以用来处理一些比较复杂的算法。
它们能够让程序的结构变得更加模块化,也方便代码的复用。
Invoke法还可以与许多框架和库一起使用,可以用来检查指定的对象是否包含某个函数,从而使用特定的接口或者属性进行调用。
虽然 Invoke法可以带来许多方便,但是它也有一些限制。
首先,它只能在多重继承的类中使用,因为它是面向对象编程语言中的一个重要特性。
另外,它无法处理静态函数或属性,因为这些函数和属性无法被实例化,也就是无法被调用。
Invoke法也不能用于非面向对象编程语言,所以程序员在开发程序时,应该考虑到这一点。
总之,Invoke法是面向对象编程中一种非常有用的函数,它可以简化代码编写,帮助程序员专注于实现业务逻辑,而不用太多时间在重复的编写代码上。
但是,由于它还是一个新的概念,所以它的使用也会有一定的困难,程序员需要熟悉它的原理。
- 1 -。
invoke计算机英语Invoke是一种在计算机科学中常用的术语,表示调用一个特定的函数或方法。
在计算机英语中,invoke的使用非常广泛,特别是在编程语言和操作系统中。
下面,我们将分步骤阐述invoke在计算机英语中的应用。
第一步:在编程语言中使用invoke在如Java、C++、Python等编程语言中,invoke是非常常见的关键词。
在函数或方法中,我们通常使用invoke关键词来调用其他函数或方法。
例如,在Java中,我们可以使用以下代码:public void printMessage(String message) {System.out.println(message);}public void main(String[] args) {String message = "Hello World";printMessage(message);}在这个程序中,我们定义了一个printMessage的函数,它可以将输入的字符串打印出来。
在main函数中,我们通过调用printMessage函数来输出字符串“Hello World”。
在这个例子中,invoke的作用就是调用printMessage函数。
第二步:在操作系统中使用invoke除了在编程语言中使用外,invoke在操作系统中也是非常重要的关键词。
在Windows操作系统中,我们可以使用invoke调用系统API 函数,从而实现一些特定的功能。
例如,在使用Win32 API开发Windows应用程序时,我们可以使用以下代码:HWND hWnd = NULL;hWnd = FindWindow("Notepad", NULL);if (hWnd != NULL) {SendMessage(hWnd, WM_CLOSE, 0, 0);}在这个程序中,我们使用了FindWindow和SendMessage两个系统API函数。
invoke[in·voke || ɪn'vəʊk]v.祈求, 实行, 恳求; 向神乞求帮助或保护; 通过巫术召唤鬼灵; 要求, 上诉; 祷告; 使命令作用, 发起某种行动 (计算机用语)同义词: appeal beg beseech entreat implore plead pray用法:1、VERB援用,援引(法律) If you invoke a law, you state that you are taking a particular actionbecause that law allows or tells you to.∙The judge invoke d an international law that protects refugees.法官援引了一项保护难民的国际法。
2、VERB引用,援引(原则、格言、名人) If you invoke something such as a principle, a saying, or a famous person, you refer to them in order to support your argument.∙He invoke d memories of Britain's near-disastrous disarmament in the 1930s...他援引了英国 20 世纪 30 年代几近灾难性的裁军事件。
∙In political matters George Washington went out of his way to avoid invoking the authority of Christ.在政治问题上,乔治·华盛顿刻意避免借助基督的权威。
3、VERB引起,唤起,激发(感情或景象,许多人认为这种用法不正确) If something such as apiece of music invokes a feeling or an image, it causes someone to have the feeling or to see the image. Many people consider this use to be incorrect.∙The music invoke d the wide open spaces of the prairies.该音乐营造出了一幅大草原上宽广辽阔的景象。
Invoke vt. 乞灵,祈求;提出或授引(以支持或证明);招鬼;借助过去式:invoked过去分词:invoked现在分词:invoking第三人称单数:invokes【动词+名词短语】1.~ sth. (against sb.) to mention or use a law, rule, etc. as areason for doing sth. 援引,援用(法律、规则等作为行动理由)例句:It is unlikely that libel laws will be invoked.不大可能诉诸诽谤法。
2.to mention a person, a theory, an example, etc. to supportyour opinions or ideas, or as a reason for sth. 提及,援引(某人、某理论、实例等作为支持)例句:She invoked several eminent scholars to back up her argument.她援引了几位赫赫有名的学者来支持她的论点。
3.to mention sb’s name to make people feel a particular thingor act in a particular way提出(某人的名字,以激发某种感觉或行动)例句:His name was invoked as a symbol of the revolution.他的名字被提出作为那次革命的象征。
4.to make a request (for help) to sb. especially a god向(某人)请求帮助;(尤指)祈求神助5.to make sb. have a particular feeling or imagine a particularscene 使产生,唤起,引起(感情或想象)6.to begin to run a program, etc.调用;激活例句:This command will invoke the HELP system.这条指令将启用“帮助”系统。
Java中的`invoke`通常与反射(reflection)相关,用于动态地调用类的方法或访问类的字段。
`invoke`方法主要存在于`ng.reflect.Method`和`ng.reflect.Constructor`等反射类中。
以下是`invoke`方法的一些常见用法:1. **调用类的方法**:```javaClass<?> clazz = SomeClass.class;Method method = clazz.getMethod("methodName", parameterType1, parameterType2, ...);Object instance = clazz.getDeclaredConstructor().newInstance();Object result = method.invoke(instance, arg1, arg2, ...);```这段代码中,我们首先获取了要调用的方法(`methodName`),然后创建了一个类的实例,最后使用`invoke`方法调用该方法,并传递所需的参数。
`invoke`方法返回方法的返回值。
2. **调用静态方法**:```javaClass<?> clazz = SomeClass.class;Method method = clazz.getMethod("staticMethodName", parameterType1, parameterType2, ...);Object result = method.invoke(null, arg1, arg2, ...);```与上述示例类似,但这次我们调用了静态方法,因此在`invoke`方法中传递了`null`作为实例。
3. **访问和修改字段**:```javaClass<?> clazz = SomeClass.class;Field field = clazz.getDeclaredField("fieldName");Object instance = clazz.getDeclaredConstructor().newInstance();// 获取字段的值Object value = field.get(instance);// 设置字段的值field.set(instance, newValue);```这段代码演示了如何使用反射访问和修改类的字段。
java的invoke方法在Java编程语言中,invoke方法是一个非常重要的概念和方法。
它用于调用一个对象的方法,并在运行时动态地执行这个方法。
invoke方法可以灵活地调用不同类型的方法,包括公共方法、私有方法、静态方法和构造方法。
在Java中,invoke方法是通过反射机制来实现的。
反射是一种能够在运行时动态地获取和操作类的信息的机制。
通过反射,我们可以获取一个类的属性、方法、构造方法等信息,然后在运行时动态地使用它们。
invoke方法就是反射机制的重要应用之一使用invoke方法调用一个方法的基本语法是:```Method method = obj.getClass(.getMethod("methodName", parameterTypes);method.invoke(obj, arguments);```其中,obj是要调用方法的对象,"methodName"是要调用的方法的名称,parameterTypes是方法的参数类型数组,arguments是方法的参数值数组。
invoke方法的返回值是被调用方法的返回值。
调用静态方法时,obj 可以为null。
下面是invoke方法的几个重要应用场景:1. 调用公共方法:invoke方法可以调用对象的公共方法,无论这个方法是否包含参数。
例如,我们可以通过invoke方法调用一个对象的toString方法来获取它的字符串表示。
```String str = "Hello World";Method toStringMethod = str.getClass(.getMethod("toString");String result = (String) toStringMethod.invoke(str);System.out.println(result); // 输出:Hello World```2. 调用私有方法:invoke方法也可以调用对象的私有方法。
在写代码的时候,发现Method可以调用子类的对象,但子类即使是改写了的Method,方法名一样,去调用父类的对象也会报错,虽然这是很符合多态的现象,也符合java的动态绑定规范,但还是想弄懂java是如何实现的,就学习了下Method的源代码。
Method的invoke方法1.先检查AccessibleObject的override属性是否为true。
AccessibleObject是Method,Field,Constructor的父类,override属性默认为false,可调用setAccessible方法改变,如果设置为true,则表示可以忽略访问权限的限制,直接调用。
2.如果不是ture,则要进行访问权限检测。
用Reflection的quickCheckMemberAccess 方法先检查是不是public的,如果不是再用Reflection.getCallerClass(1)方法获得到调用这个方法的Class,然后做是否有权限访问的校验,校验之后缓存一次,以便下次如果还是这个类来调用就不用去做校验了,直接用上次的结果,(很奇怪用这种方式缓存,因为这种方式如果下次换个类来调用的话,就不用会缓存了,而再验证一遍,把这次的结果做为缓存,但上一次的缓存结果就被冲掉了。
这是一个很简单的缓冲机制,只适用于一个类的重复调用)。
3.调用MethodAccessor的invoke方法。
每个Method对象包含一个root对象,root 对象里持有一个MethodAccessor对象。
我们获得的Method独享相当于一个root对象的镜像,所有这类Method共享root里的MethodAccessor对象,(这个对象由Reflectio nFactory方法生成,ReflectionFactory对象在Method类中是static final的由native 方法实例化)。
ReflectionFactory生成MethodAccessor:如果noInflation的属性为true则直接返回MethodAccessorGenerator创建的一个MethodAccessor。
否则返回DelegatingMethodAccessorImpl,并将他与一个NativeMethodAccessorI mpl互相引用。
但DelegatingMethodAccessorImpl执行invoke方法的时候又委托给N ativeMethodAccessorImpl了。
再一步深入4.NativeMethodAccessorImpl的invkoe方法:调用natiave方法invoke0执行方法调用.注意这里有一个计数器numInvocations,每调用一次方法+1,当比ReflectionFactory. inflationThreshold(15)大的时候,用MethodAccessorGenerator创建一个MethodAcc essor,并把之前的DelegatingMethodAccessorImpl引用替换为现在新创建的。
下一次DelegatingMethodAccessorImpl就不会再交给NativeMethodAccessorImpl执行了,而是交给新生成的java字节码的MethodAccessor。
MethodAccessorGenerator使用了asm字节码动态加载技术,暂不深入研究。
总结一个方法可以生成多个Method对象,但只有一个root对象,主要用于持有一个Me thodAccessor对象,这个对象也可以认为一个方法只有一个,相当于是static的。
因为M ethod的invoke是交给MethodAccessor执行的,所以我所想要知道的答案在Method Accessor的invoke中,深入MethodAccessor:------------------------------------------MethodAccessor---------------------------------假如有这么一个类A:public class A {public void foo(String name) {System.out.println("Hello, " + name);}}可以编写另外一个类来反射调用A上的方法:import ng.reflect.Method;public class TestClassLoad {public static void main(String[] args) throws Exception {Class<?> clz = Class.forName("A");Object o = clz.newInstance();Method m = clz.getMethod("foo", String.class);for (int i = 0; i < 16; i++) {m.invoke(o, Integer.toString(i));}}}注意到TestClassLoad类上不会有对类A的符号依赖——也就是说在加载并初始化Test ClassLoad类时不需要关心类A的存在与否,而是等到main()方法执行到调用Class.for Name()时才试图对类A做动态加载;这里用的是一个参数版的forName(),也就是使用当前方法所在类的ClassLoader来加载,并且初始化新加载的类。
……好吧这个细节跟主题没啥关系。
回到主题。
这次我的测试环境是Sun的JDK 1.6.0 update 13 build 03。
编译上述代码,并在执行TestClassLoad时加入-XX:+TraceClassLoading参数(或者-verbose:c lass或者直接-verbose都行),如下:控制台命令java -XX:+TraTestClassLoad ceClassLoading可以看到输出了一大堆log,把其中相关的部分截取出来如下:[Loaded TestClassLoad from file:/D:/temp_code/test_java_classload/][Loaded A from file:/D:/temp_code/test_java_classload/][Loaded sun.reflect.NativeMethodAccessorImpl from shared objects file] [Loaded sun.reflect.DelegatingMethodAccessorImpl from shared objects file] Hello, 0Hello, 1Hello, 2Hello, 3Hello, 4Hello, 5Hello, 6Hello, 7Hello, 8Hello, 9Hello, 10Hello, 11Hello, 12Hello, 13Hello, 14[Loaded sun.reflect.ClassFileConstants from shared objects file][Loaded sun.reflect.AccessorGenerator from shared objects file][Loaded sun.reflect.MethodAccessorGenerator from shared objects file] [Loaded sun.reflect.ByteVectorFactory from shared objects file][Loaded sun.reflect.ByteVector from shared objects file][Loaded sun.reflect.ByteVectorImpl from shared objects file][Loaded sun.reflect.ClassFileAssembler from shared objects file][Loaded sun.reflect.UTF8 from shared objects file][Loaded ng.Void from shared objects file][Loaded bel from shared objects file][Loaded bel$PatchInfo from shared objects file][Loaded java.util.AbstractList$Itr from shared objects file][Loaded sun.reflect.MethodAccessorGenerator$1from shared objects file] [Loaded sun.reflect.ClassDefiner from shared objects file][Loaded sun.reflect.ClassDefiner$1from shared objects file][Loaded sun.reflect.GeneratedMethodAccessor1 from __JVM_DefineClass__] Hello, 15可以看到前15次反射调用A.foo()方法并没有什么稀奇的地方,但在第16次反射调用时似乎有什么东西被触发了,导致JVM新加载了一堆类,其中就包括[Loaded sun.reflect. GeneratedMethodAccessor1 from __JVM_DefineClass__]这么一行。
这是哪里来的呢?先来看看JDK里Method.invoke()是怎么实现的。
ng.reflect.Method:public finalclass Method extends AccessibleObject implements GenericDeclaration,Member {// ...private volatile MethodAccessor methodAccessor;// For sharing of MethodAccessors. This branching structure is// currently only two levels deep (i.e., one root Method and// potentially many Method objects pointing to it.)private Method root;// ...public Object invoke(Object obj, Object... args)throws IllegalAccessException, IllegalArgumentException,InvocationTargetException{if(!override) {if(!Reflection.quickCheckMemberAccess(clazz, modifiers)) {Class caller = Reflection.getCallerClass(1);Class targetClass = ((obj == null|| !Modifier.isProtected(mod ifiers))? clazz: obj.getClass());boolean cached;synchronized(this) {cached = (securityCheckCache == caller)&& (securityCheckTargetClassCache == targetClass);}if(!cached) {Reflection.ensureMemberAccess(caller, clazz, obj, modifie rs);synchronized(this) {securityCheckCache = caller;securityCheckTargetClassCache = targetClass;}}}}if(methodAccessor == null) acquireMethodAccessor();return methodAccessor.invoke(obj, args);}// NOTE that there is no synchronization used here. It is correct// (though not efficient) to generate more than one MethodAccessor// for a given Method. However, avoiding synchronization will// probably make the implementation more scalable.private void acquireMethodAccessor() {// First check to see if one has been created yet, and take it// if soMethodAccessor tmp = null;if(root != null) tmp = root.getMethodAccessor();if(tmp != null) {methodAccessor = tmp;return;}// Otherwise fabricate one and propagate it up to the roottmp = reflectionFactory.newMethodAccessor(this);setMethodAccessor(tmp);}// ...}可以看到Method.invoke()实际上并不是自己实现的反射调用逻辑,而是委托给sun.reflect.Met hodAccessor来处理。