简体   繁体   English

通过反射调用实例方法,好像它是静态的

[英]Invoking instance method as if it was static through reflection

From simplified perspective, all methods in .Net are actually static. 从简化的角度来看,.Net中的所有方法实际上都是静态的。 Instance methods invoked by implicitly passing reference to this to first method argument. 通过隐式地将this引用传递给第一个方法参数来调用实例方法。 So, it is possible to call instance method without actually supplying correct instance, making it to behave like static method. 因此,可以在不实际提供正确实例的情况下调用实例方法,使其行为类似于静态方法。 Eg it is possible to call string.Equals(string s) as null.Equals(null) either by dynamic emitting call OpCode instead of callvirt or writing corresponding IL code by hand. 例如,可以通过动态发出call OpCode而不是callvirt来调用string.Equals(string s)null.Equals(null)callvirt编写相应的IL代码。 As I recall, this situation maybe actually encountered if the code was jitted in runtime. 我记得,如果在运行时添加代码,可能会遇到这种情况。 And there would be no problem if this is not used within method body. 如果就没有问题, this是不是方法体中使用。
This thing provides demonstration that methods are actually static in .Net. 这件事证明了.Net中的方法实际上是静态的。 I'd like to know if there are similar tricks in Java. 我想知道Java中是否有类似的技巧。 I've looked through Method.invoke() - it is very thorough in checking that instance methods are not invoked without correct instances, and NullPointerException is guaranteed for null instance. 我已经仔细研究过Method.invoke() -检查是否没有正确的实例就不会调用实例方法是非常彻底的,并且为空实例保证了NullPointerException Mostly because all methods in Java are virtual, and for virtual call correct type is required. 主要是因为Java中的所有方法都是虚拟的,对于虚拟调用,需要正确的类型。
So, is there any trick way to call instance method as if it was static in Java (maybe due to some optimization, eg if only one method implementation exists in runtime, virtual call can be changed to non-virtual call)? 因此,是否有任何技巧可以像在Java中那样将其实例化为静态方法(可能是由于某种优化,例如,如果运行时仅存在一个方法实现,则可以将虚拟调用更改为非虚拟调用)? Or is forbidden due to possible existence of real instance methods (every instance of type has its own method body for that method, not shared between them)? 还是由于可能存在实实例方法而被禁止(每个类型的实例都具有该方法的自身方法主体,而不在它们之间共享)?

Certainly not from Java code, no. 当然不是来自Java代码,不是。

If you hand-roll bytecode, then perhaps you could use an invokestatic operation to invoke an instance method, but the result of doing so is not defined in the JVM specifications. 如果您手动滚动字节码,那么也许可以使用invokestatic操作来调用实例方法,但是这样做的结果未在JVM规范中定义。 Different JVM implementations could -- and probably do -- handle it differently. 不同的JVM实现可以并且可能会以不同的方式处理它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM