动态执行java代码,Java代码的静态编译和动态编译中的问题是什么

1,Java代码的静态编译和动态编译中的问题是什么Java代码正常是静态编译成字节码,由对应平台的JVM加载执行,静态编译无法动态扩展功能 。动态编译有两种方式实现:1. 从源码编译 , 需要调用Java Compiler , 程序需要运行于JDK(而不是JRE)之上 。2. 动态字节码生成技术(如CGLib、ASM)创建类 。动态编译可以简化代码,增强类功能,但也带来了代码复杂度,线上不易维护 。【动态执行java代码,Java代码的静态编译和动态编译中的问题是什么】
2,如何在java中动态执行一段代码有点难度 ,,,,, 需要动态编译成类、、、、然后反射调用首先你可以使用输入输出流(或者你说的可能是要用反射得到程序结果来解析)解析做出*.java文件 。然后可以使用runtime调用dos下的java编译命令编译取得class文件 。然后使用classloader,反射等组合执行生成的class文件 。
3,JAVA里如何实现动态算法如果只是简单的加减乘除,采用递归方式,按照运算符优先级计算,最后得到结果如果复杂一点 , 可以采用动态编译,你写的字符串算式,就变成java代码,最后采用反射执行两种方式 。这个可以使用格式化字符串完成 。用法参见:formatter类 。如://格式:%[argument_index$][flags][width][.precision]conversionstring result = string.format("%1$20s", "abc");int F = A * B ;int G = C + D ;if ( F > 0 || G == 0){ (这里放你要运行的东西) ;}不知道是不是你想要的 。。。你提问的问题有点模糊啊 。。
4,java 动态代理实例1. 代理模式代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问 。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用 。代理模式一般涉及到三个角色:抽象角色:声明真实对象和代理对象的共同接口;代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象 。同时 , 代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装 。真实角色:代理角色所代表的真实对象,是我们最终要引用的对象 。以下以《Java与模式》中的示例为例:抽象角色:abstractpublicclassSubjectabstractpublicvoidrequest(); }真实角色:实现了Subject的request()方法 。publicclassRealSubjectextendsSubjectpublicRealSubject()publicvoidrequest()System.out.println( " From real subject. " );}}代理角色: publicclassProxySubjectextendsSubjectprivateRealSubject realSubject;// 以真实角色作为代理角色的属性publicProxySubject()publicvoidrequest()preRequest();if ( realSubject==null)realSubject=newRealSubject();}realSubject.request();// 此处执行真实对象的request方法postRequest();}客户端调用:Subject sub = newProxySubject(); Sub.request(); 由以上代码可以看出,客户实际需要调用的是RealSubject类的request()方法,现在用ProxySubject来代理 RealSubject类,同样达到目的,同时还封装了其他方法(preRequest(),postRequest()),可以处理一些其他问题 。另外,如果要按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性 。但是实际使用时,一个真实角色必须对应一个 代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决 。2.动态代理类Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:(1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args) 。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组 。这个抽象方法在代理类中动态实现 。(2).Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject , 其中主要包含以下内容:Protected Proxy(InvocationHandler h):构造函数 , 估计用于给内部的h赋值 。Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器 , interfaces是真实类所拥有的全部接口的数组 。Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法) 。所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它 , 然后该class就宣称它实现了这些 interface 。你当然可以把该class的实例当作这些interface中的任何一个来用 。当然啦 , 这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler , 由它接管实际的工作 。在使用动态代理类时 , 我们必须实现InvocationHandler接口 , 以第一节中的示例为例:抽象角色(之前是抽象类,此处应改为接口): publicinterfaceSubjectabstractpublicvoidrequest(); }具体角色RealSubject:publicclassRealSubjectimplementsSubjectpublicRealSubject()publicvoidrequest()System.out.println( " From real subject. " );}}代理处理器:importjava.lang.reflect.Method;importjava.lang.reflect.InvocationHandler;publicclassDynamicSubjectimplementsInvocationHandlerprivateObject sub;publicDynamicSubject()publicDynamicSubject(Object obj)sub=obj;}publicObject invoke(Object proxy, Method method, Object[] args)throwsThrowableSystem.out.println( " before calling"+method);method.invoke(sub,args);System.out.println( " after calling"+method);returnnull ; }}该代理类的内部属性为Object类,实际使用时通过该类的构造函数DynamicSubject(Object obj)对其赋值;此外,在该类还实现了invoke方法,该方法中的method.invoke(sub,args);其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,args为执行被代理对象相应操作所需的参数 。通过动态代理类,我们可以在调用之前或之后执行一些相关操作 。客户端:importjava.lang.reflect.InvocationHandler; importjava.lang.reflect.Proxy; importjava.lang.reflect.Constructor; importjava.lang.reflect.Method; publicclassClientstaticpublicvoidmain(String[] args)throwsThrowableRealSubject rs=newRealSubject();// 在这里指定被代理类InvocationHandler ds=newDynamicSubject(rs);Class cls=rs.getClass();// 以下是一次性生成代理Subject subject=(Subject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(),ds );subject.request(); }程序运行结果:before calling public abstract void Subject.request()From real subject.after calling public abstract void Subject.request()通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系 。5,java动态代理怎样实现动态代理设计到java的一个底层代码,源代码看不到,cglib也可实现动态代理和动态继承,不必对他的底层深究,涉及到编译原理啦 import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;// 定义一个接口interface Subject {public void run();}// 真正要执行的类class RealSubject implements Subject {public void run() {System.out.println("this is a real subject!");}}// 动态代理类public class DymanicProxy implements InvocationHandler {Object obj;// 构造方法public DymanicProxy(Object obj) {super();this.obj = obj;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("------before method------");// 动态代理执行Subject类的run方法Object object = method.invoke(this.obj, new Object[] {});System.out.println("------after method------");return object;}// 主方法public static void main(String[] args) {Subject subject = new RealSubject();// 构造obj的对象InvocationHandler dymanicProxy = new DymanicProxy(subject);// 生成代理类Proxy0/** 代理类具用以下属性:** 代理类是公共的、最终的,而不是抽象的 。未指定代理类的非限定名称 。但是,以字符串 "$Proxy" 开头的类名空间应该为代理类保留 。* 代理类扩展 java.lang.reflect.Proxy 。代理类会按同一顺序准确地实现其创建时指定的接口 。* 如果代理类实现了非公共接口 , 那么它将在与该接口相同的包中定义 。否则,代理类的包也是未指定的 。注意,包密封将不阻止代理类在运行时在特定包中的成功定义,也不会阻止相同类加载器和带有特定签名的包所定义的类 。* 由于代理类将实现所有在其创建时指定的接口,所以对其 Class 对象调用 getInterfaces* 将返回一个包含相同接口列表的数组(按其创建时指定的顺序),对其 Class 对象调用 getMethods* 将返回一个包括这些接口中所有方法的 Method 对象的数组,并且调用 getMethod 将会在代理接口中找到期望的一些方法 。如果* Proxy.isProxyClass 方法传递代理类(由 Proxy.getProxyClass 返回的类,或由* Proxy.newProxyInstance 返回的对象的类) , 则该方法返回 true , 否则返回 false 。代理类的* java.security.ProtectionDomain 与由引导类加载器(如* java.lang.Object)加载的系统类相同,原因是代理类的代码由受信任的系统代码生成 。此保护域通常被授予* java.security.AllPermission 。每个代理类都有一个可以带一个参数(接口 InvocationHandler* 的实现)的公共构造方法 , 用于设置代理实例的调用处理程序 。并非必须使用反射 API 才能访问公共构造方法,通过调用* Proxy.newInstance 方法(将调用 Proxy.getProxyClass* 的操作和调用带有调用处理程序的构造方法结合在一起)也可以创建代理实例 。*/Subject subject2 = (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), dymanicProxy);// 执行run方法subject2.run();}}楼主,我给你写了个例子,带注释的,刚开始是挺难理解的,推荐你看一下马士兵讲的动态代理,他是由浅入深的详解动态代理一般是用来做框架的,Spring里的AOP(面向切面编程)就是基于动态代理的 。它是基于反射来的前面几个人的代码我不知道你有没有看懂,我觉得不是很好 。你可以先看看下面的图,先理解动态代理的意思 。图的解释我跟在后面看完了图,我想先问你个问题:动态代理 , 到底代理了什么?----------从图中可以看出就是红字的部分 。就是在某个或模块业务方法前后会执行你希望代理的功能,这样系统执行业务方法的时候,代理的部分就能自动执行了 。一般代理的内容会封装在叫做Adice(建议)的类中,这样当需要修改代码功能的时候,只要修改Advice就行了,而不用修改业务方法 。具体代码如下:(完整,已测试)Advice接口:实现Advice接口的TargetAdvice类:主测试类:DynamicProxyTest:运行结果:前置系统功能代码 后置系统功能代码 前置系统功能代码 后置系统功能代码 前置系统功能代码 后置系统功能代码 代码传不上来,要的话发给你在目前的Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现 。其实现主要通过是java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口 。Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现,如下,HelloWorld接口定义的业务方法,HelloWorldImpl是HelloWorld接口的实现 , HelloWorldHandler是InvocationHandler接口实现 。代码如下:业务接口:public interface HelloWorld {void sayHelloWorld() ;} 业务接口实现:public class HelloWorldImpl implements HelloWorld {public void sayHelloWorld() {System.out.println("Hello World!");}} InvocationHandler实现 , 需要在接口方法调用前后加入一部份处理工作,这里仅仅在方法调用前后向后台输出两句字符串,其代码如下:import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class HelloWorldHandler implements InvocationHandler {//要代理的原始对象private Object objOriginal;/*** 构造函数 。* @param obj 要代理的原始对象 。*/public HelloWorldHandler(Object obj) {this.objOriginal = obj ;}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object result ;//方法调用之前doBefore();//调用原始对象的方法result = method.invoke(this.objOriginal ,args);//方法调用之后doAfter();return result ;}private void doBefore() {System.out.println("before method invoke!");}private void doAfter() {System.out.println("after method invoke!");}} 测试代码:import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class Test {public static void main(String[] args) {HelloWorld hw = new HelloWorldImpl();InvocationHandler handler = new HelloWorldHandler(hw);HelloWorld proxy = (HelloWorld) Proxy.newProxyInstance(hw.getClass().getClassLoader(),hw.getClass().getInterfaces(),handler);proxy.sayHelloWorld();}} ?首先获取一个业务接口的实现对象;?获取一个InvocationHandler实现,此处是HelloWorldHandler对象;?创建动态代理对象;?通过动态代理对象调用sayHelloWorld()方法,此时会在原始对象HelloWorldImpl. sayHelloWorld()方法前后输出两句字符串 。运行测试类输出如下:before method invoke!Hello World!after method invoke! 此处Test类中的方法调用代码比较多 , 在我们的实际应用中可以通过配置文件来来简化客户端的调用实现 。另外也可以通过动态代理来实现简单的AOP

    推荐阅读