java 在运行时将新方法和属性注入到类中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1419758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Inject New Methods and Properties into Classes During Runtime
提问by Cheok Yan Cheng
Is there any way we can inject new methods and properties into classes during run-time.
有什么方法可以在运行时将新方法和属性注入到类中。
http://nurkiewicz.blogspot.com/2009/09/injecting-methods-at-runtime-to-java.htmlstates we may do that by using Groovy.
http://nurkiewicz.blogspot.com/2009/09/injecting-methods-at-runtime-to-java.html声明我们可以通过使用 Groovy 来做到这一点。
Is it possible by just doing using Java?
仅使用Java就可以吗?
回答by Stephen C
Is it possible by just doing using Java?
仅使用Java就可以吗?
The simple answer is an emphatic "You don't want to do that!".
简单的回答是强调“你不想那样做!”。
It is technically possible, but not without resorting to extremely complex, expensive and fragile tricks like bytecode modification1. And even then, you have to rely on dynamic loading to access the modified type and (probably) reflection to make use of its new members. In short, you would be creating lots of pain for yourself, for little if any gain.
这在技术上是可行的,但需要借助极其复杂、昂贵和脆弱的技巧,例如字节码修改1。即便如此,您也必须依靠动态加载来访问修改后的类型和(可能)反射以利用其新成员。简而言之,你会为自己制造很多痛苦,但收获甚微。
Java is a statically typed language, and adding / modifying class type signatures can break the static typing contract of a class.
Java 是一种静态类型语言,添加/修改类类型签名会破坏类的静态类型约定。
1 - AspectJ and the like allow you to inject additional behaviour into a class, but it is probably not the "runtime" injection that you are after. Certainly, the injected methods won't be available for statically compiled code to call.
1 - AspectJ 等允许您向类中注入额外的行为,但这可能不是您所追求的“运行时”注入。当然,注入的方法将不可用于静态编译的代码调用。
回答by skaffman
You can do some quite funky things with AOP, although genuine modification of classes at runtime is a pretty hairy technique that needs a lot of classloading magic and sleight of hand.
您可以使用 AOP 做一些非常时髦的事情,尽管在运行时真正修改类是一项非常棘手的技术,需要大量的类加载魔法和技巧。
What is easier is using AOP techniques to generate a subclass of your target class and to introduce new methods into this instead, what AOP called a "mixin" or "introduction". See hereto read how Spring AOP does it, although this may be quite lame compared to what you're actually trying to achieve.
更容易的是使用 AOP 技术生成目标类的子类,并在其中引入新方法,AOP 称之为“混合”或“介绍”。请参阅此处了解 Spring AOP 如何做到这一点,尽管与您实际尝试实现的目标相比,这可能相当蹩脚。
回答by Chris Thompson
So if you were really crazy, you could do something like what they outline here. What you could do is load the .java file, find the correct insertion point, add whatever methods you need to, call the java compiler and reload the class. Good luck debugging that mess though :)
所以如果你真的疯了,你可以做一些类似于他们在这里概述的事情。您可以做的是加载 .java 文件,找到正确的插入点,添加您需要的任何方法,调用 java 编译器并重新加载类。祝你好运调试那个烂摊子:)
EditThisactually might be of some use...
编辑这实际上可能有一些用...
回答by gustafc
Is it possible by just doing using Java?
仅使用Java就可以吗?
Quite so, the "only" thing you have to do is define an instrumentation agentwhich supplies an appropriate ClassFileTransformer, and you'll have to use reflection to invoke the added methods. Odds are this isn't what you want to do, though, but it's doable and there's a well-defined interface for it. If you want to modify existing methods you may be interested in something like AspectJ.
确实如此,您必须做的“唯一”事情是定义一个提供适当的检测代理ClassFileTransformer,并且您必须使用反射来调用添加的方法。不过,这很可能不是您想要做的,但它是可行的,并且有一个明确定义的接口。如果您想修改现有方法,您可能会对AspectJ 之类的东西感兴趣。
回答by mfx
While it might be possible, it is not useful.
虽然它可能是可能的,但它没有用。
How would you access these new fields and methods?
您将如何访问这些新字段和方法?
You could not use these methods and fields directly (as "ordinary" fields and methods), since they wouldn't be compiled in.
您不能直接使用这些方法和字段(作为“普通”字段和方法),因为它们不会被编译。
If all you want is the possibility to add "properties" and "methods", you can use a Map<String, Object>for the "dynamic properties", and a Map<String, SuitableInterface>for the "dynamic methods", and look them up by name.
如果您想要的只是添加“属性”和“方法”的可能性,您可以将 aMap<String, Object>用于“动态属性”,将 aMap<String, SuitableInterface>用于“动态方法”,并按名称查找它们。
If you need an extension language for Java, an embedded dynamic language (such as Javascript, or Groovy) can be added; most of these can access arbitrary java objects and methods.
如果需要Java的扩展语言,可以添加嵌入式动态语言(如Javascript,或Groovy);其中大部分可以访问任意java对象和方法。

