那些使java更具灵活性的技术

java的反射,注解,内置的脚本引擎,编译器API和SPI都在一定程度上更具灵活,如果能使用得当并配合好的设计模式,通常能使开发和维护得到事半功倍的效果。

[文件] ScriptTest.java
package com.hongyuan.test;
 
import java.util.List;
 
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
 
public class ScriptTest {
 
    public static void main(String[] args) throws ScriptException, NoSuchMethodException {
        //创建脚本引擎管理类
        ScriptEngineManager manager=new ScriptEngineManager();
         
        //查询可用的脚本引擎
        List<ScriptEngineFactory> factoryList=manager.getEngineFactories();
        for(ScriptEngineFactory factory:factoryList){
            String name=factory.getEngineName();
            String language=factory.getLanguageName();
            System.out.println(name+"-->"+language);
        }
        System.out.println("================================================");
         
        //获取javaScript脚本引擎
        ScriptEngine jsEngine=manager.getEngineByName("JavaScript");
         
        //向脚本引擎传入变量
        jsEngine.put("k", 100);
         
        //计算表达式
        jsEngine.eval("k=k*3+24");
         
        //从脚本引擎查询变量
        Object k=jsEngine.get("k");
        System.out.println(k);
         
        System.out.println("================================================");
         
        jsEngine.eval("function sayHello(){ println('hello,World!!!!'); }");
         
        //调用脚本中的函数
        ((Invocable)jsEngine).invokeFunction("sayHello");
        //或
        jsEngine.eval("sayHello();");
         
        //脚本中使用java(下面代码展示如何在脚本中使用java创建窗体)
        String script="var jf=new javax.swing.JFrame();"
                + "jf.setTitle('hello,Script');"
                + "jf.setBounds(200,100,400,300);"
                + "jf.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);"
                + "jf.setVisible(true);";
        jsEngine.eval(script);
    }
 
}
[文件] ProxyTest.java
package com.hongyuan.test;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
public class ProxyTest {
 
    public static void main(String[] args) {
         
        //获取接口代理对象
        Demo demo=(Demo)Proxy.newProxyInstance(Demo.class.getClassLoader(), 
                new Class[]{Demo.class},new InvocationHandler() {
                     
                    //代理对象上的方法调用时会转交到此方法进行处理
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {
                        Object result=null;
                         
                        System.out.println(method.getName()+"-->方法调用前!!!");
                         
                        if("add".equals(method.getName())){
                            int sum=0;
                            for(int i=0,length=args.length;i<length;i++){
                                sum+=(int)args[i];
                            }
                            result=sum;
                        }else if("sayHello".equals(method.getName())){
                            System.out.println("hello,World!!!");
                        }else{
                            throw new Exception("你调用的方法尚未实现!!!");
                        }
                         
                        System.out.println(method.getName()+"-->方法调用后!!!");
                        return result;
                    }
        });
         
        System.out.println(demo.add(12, 12));
        demo.sayHello();
        demo.makeMoney();
    }
 
}
 
interface Demo{
    public int add(int num1,int num2);
    public void sayHello();
    public void makeMoney();
}